From aac785171ee05d99e0190442a40bad26943e285f Mon Sep 17 00:00:00 2001 From: Mohsen Date: Tue, 10 Sep 2024 19:36:38 +0330 Subject: [PATCH 01/24] Add egeniouss receiver. --- src/core/CMakeLists.txt | 2 + src/core/positioning/abstractgnssreceiver.h | 1 + src/core/positioning/egenioussreceiver.cpp | 60 +++++++++++++++++++++ src/core/positioning/egenioussreceiver.h | 26 +++++++++ 4 files changed, 89 insertions(+) create mode 100644 src/core/positioning/egenioussreceiver.cpp create mode 100644 src/core/positioning/egenioussreceiver.h 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/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..eb61871228 --- /dev/null +++ b/src/core/positioning/egenioussreceiver.cpp @@ -0,0 +1,60 @@ +#include "egenioussreceiver.h" + +#include + +EgenioussReceiver::EgenioussReceiver( QObject *parent ) + : AbstractGnssReceiver( parent ), mTcpSocket( new QTcpSocket( this ) ) +{ + connect( mTcpSocket, &QTcpSocket::readyRead, this, &EgenioussReceiver::onReadyRead ); + connect( mTcpSocket, &QTcpSocket::errorOccurred, this, &EgenioussReceiver::onErrorOccurred ); +} + +void EgenioussReceiver::handleConnectDevice() +{ + mTcpSocket->connectToHost( QHostAddress::LocalHost, 1235 ); + + if ( !mTcpSocket->waitForConnected( 3000 ) ) + { + setValid( false ); + mLastError = mTcpSocket->errorString(); + emit lastErrorChanged( mLastError ); + } + else + { + setValid( true ); + mSocketState = QAbstractSocket::ConnectedState; + emit socketStateChanged( mSocketState ); + } +} + +void EgenioussReceiver::handleDisconnectDevice() +{ + if ( mTcpSocket->state() == QAbstractSocket::ConnectedState ) + { + mTcpSocket->disconnectFromHost(); + mTcpSocket->waitForDisconnected(); + } +} + +QList> EgenioussReceiver::details() +{ + QList> dataList; + dataList.append( qMakePair( QString( "Last Received Data" ), mReceivedData ) ); + return dataList; +} + +void EgenioussReceiver::onReadyRead() +{ + mReceivedData = mTcpSocket->readAll(); + if ( valid() ) + { + qDebug() << "Received Data:" << mReceivedData; + } +} + +void EgenioussReceiver::onErrorOccurred( QAbstractSocket::SocketError socketError ) +{ + mLastError = mTcpSocket->errorString(); + emit lastErrorChanged( mLastError ); + qDebug() << "Socket Error:" << mLastError; +} diff --git a/src/core/positioning/egenioussreceiver.h b/src/core/positioning/egenioussreceiver.h new file mode 100644 index 0000000000..980d8cadfd --- /dev/null +++ b/src/core/positioning/egenioussreceiver.h @@ -0,0 +1,26 @@ +#pragma once + +#include "abstractgnssreceiver.h" + +#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 onErrorOccurred( QAbstractSocket::SocketError socketError ); + + private: + QTcpSocket *mTcpSocket = nullptr; + QString mReceivedData; +}; From 2f2e5e7ab948966b4b2b503d86a0b14eebde2a43 Mon Sep 17 00:00:00 2001 From: Mohsen Date: Tue, 10 Sep 2024 22:43:30 +0330 Subject: [PATCH 02/24] Select EgenioussDevice. --- src/core/positioning/egenioussreceiver.cpp | 10 ++++++++-- src/core/positioning/positioning.cpp | 5 +++++ src/core/positioning/positioningdevicemodel.cpp | 3 +++ src/core/positioning/positioningdevicemodel.h | 1 + src/qml/PositioningDeviceSettings.qml | 12 +++++++++++- 5 files changed, 28 insertions(+), 3 deletions(-) diff --git a/src/core/positioning/egenioussreceiver.cpp b/src/core/positioning/egenioussreceiver.cpp index eb61871228..a256ee98dc 100644 --- a/src/core/positioning/egenioussreceiver.cpp +++ b/src/core/positioning/egenioussreceiver.cpp @@ -11,16 +11,19 @@ EgenioussReceiver::EgenioussReceiver( QObject *parent ) void EgenioussReceiver::handleConnectDevice() { + qDebug() << __FUNCTION__; mTcpSocket->connectToHost( QHostAddress::LocalHost, 1235 ); if ( !mTcpSocket->waitForConnected( 3000 ) ) { + qDebug() << __FUNCTION__ << __LINE__; setValid( false ); mLastError = mTcpSocket->errorString(); emit lastErrorChanged( mLastError ); } else { + qDebug() << __FUNCTION__ << __LINE__; setValid( true ); mSocketState = QAbstractSocket::ConnectedState; emit socketStateChanged( mSocketState ); @@ -29,6 +32,7 @@ void EgenioussReceiver::handleConnectDevice() void EgenioussReceiver::handleDisconnectDevice() { + qDebug() << __FUNCTION__; if ( mTcpSocket->state() == QAbstractSocket::ConnectedState ) { mTcpSocket->disconnectFromHost(); @@ -38,6 +42,7 @@ void EgenioussReceiver::handleDisconnectDevice() QList> EgenioussReceiver::details() { + qDebug() << __FUNCTION__; QList> dataList; dataList.append( qMakePair( QString( "Last Received Data" ), mReceivedData ) ); return dataList; @@ -45,10 +50,11 @@ QList> EgenioussReceiver::details() void EgenioussReceiver::onReadyRead() { + qDebug() << __FUNCTION__; mReceivedData = mTcpSocket->readAll(); if ( valid() ) { - qDebug() << "Received Data:" << mReceivedData; + qDebug() << __FUNCTION__ << "Received Data:" << mReceivedData; } } @@ -56,5 +62,5 @@ void EgenioussReceiver::onErrorOccurred( QAbstractSocket::SocketError socketErro { mLastError = mTcpSocket->errorString(); emit lastErrorChanged( mLastError ); - qDebug() << "Socket Error:" << mLastError; + qDebug() << __FUNCTION__ << "Socket Error:" << mLastError; } 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/positioningdevicemodel.cpp b/src/core/positioning/positioningdevicemodel.cpp index 83ba568868..f4577cdf6f 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:%1" ).arg( device.settings.value( QStringLiteral( "address" ) ).toString() ); } 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/qml/PositioningDeviceSettings.qml b/src/qml/PositioningDeviceSettings.qml index a9b3d97e47..30d80ba454 100644 --- a/src/qml/PositioningDeviceSettings.qml +++ b/src/qml/PositioningDeviceSettings.qml @@ -95,7 +95,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 +130,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_serial_port_receiver_black_24dp'); } return ''; } @@ -154,6 +156,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_serial_port_receiver_black_24dp'); } return ''; } @@ -177,6 +181,10 @@ Popup { name: qsTr('UDP (NMEA)') value: PositioningDeviceModel.UdpDevice } + ListElement { + name: qsTr('Egeniouss') + value: PositioningDeviceModel.EgenioussDevice + } } Loader { @@ -193,6 +201,8 @@ Popup { return "qrc:/qml/UdpDeviceChooser.qml"; case PositioningDeviceModel.SerialPortDevice: return "qrc:/qml/SerialPortDeviceChooser.qml"; + case PositioningDeviceModel.EgenioussDevice: + return "qrc:/qml/TcpDeviceChooser.qml"; } return ''; } From f02339acbe8a52f0336f91d91c35dbec352acf34 Mon Sep 17 00:00:00 2001 From: Mohsen Date: Thu, 12 Sep 2024 13:04:18 +0330 Subject: [PATCH 03/24] Refresh PositioningInformationModel on device details change. --- src/core/positioning/abstractgnssreceiver.h | 1 + src/core/positioning/egenioussreceiver.cpp | 11 ++--------- src/core/positioning/positioning.cpp | 2 ++ src/core/positioning/positioning.h | 2 +- src/core/positioning/positioninginformationmodel.cpp | 2 ++ 5 files changed, 8 insertions(+), 10 deletions(-) diff --git a/src/core/positioning/abstractgnssreceiver.h b/src/core/positioning/abstractgnssreceiver.h index 0688ea1e03..6fdde7bbd1 100644 --- a/src/core/positioning/abstractgnssreceiver.h +++ b/src/core/positioning/abstractgnssreceiver.h @@ -64,6 +64,7 @@ class AbstractGnssReceiver : public QObject virtual QList> details() { return {}; } signals: + void detailsChanged(); void validChanged(); void lastGnssPositionInformationChanged( GnssPositionInformation &lastGnssPositionInformation ); void socketStateChanged( QAbstractSocket::SocketState socketState ); diff --git a/src/core/positioning/egenioussreceiver.cpp b/src/core/positioning/egenioussreceiver.cpp index a256ee98dc..8500d07c40 100644 --- a/src/core/positioning/egenioussreceiver.cpp +++ b/src/core/positioning/egenioussreceiver.cpp @@ -11,19 +11,16 @@ EgenioussReceiver::EgenioussReceiver( QObject *parent ) void EgenioussReceiver::handleConnectDevice() { - qDebug() << __FUNCTION__; mTcpSocket->connectToHost( QHostAddress::LocalHost, 1235 ); if ( !mTcpSocket->waitForConnected( 3000 ) ) { - qDebug() << __FUNCTION__ << __LINE__; setValid( false ); mLastError = mTcpSocket->errorString(); emit lastErrorChanged( mLastError ); } else { - qDebug() << __FUNCTION__ << __LINE__; setValid( true ); mSocketState = QAbstractSocket::ConnectedState; emit socketStateChanged( mSocketState ); @@ -32,7 +29,6 @@ void EgenioussReceiver::handleConnectDevice() void EgenioussReceiver::handleDisconnectDevice() { - qDebug() << __FUNCTION__; if ( mTcpSocket->state() == QAbstractSocket::ConnectedState ) { mTcpSocket->disconnectFromHost(); @@ -42,19 +38,17 @@ void EgenioussReceiver::handleDisconnectDevice() QList> EgenioussReceiver::details() { - qDebug() << __FUNCTION__; QList> dataList; - dataList.append( qMakePair( QString( "Last Received Data" ), mReceivedData ) ); + dataList.append( qMakePair( QString( "Egeniouss" ), QVariant::fromValue( mReceivedData ) ) ); return dataList; } void EgenioussReceiver::onReadyRead() { - qDebug() << __FUNCTION__; mReceivedData = mTcpSocket->readAll(); if ( valid() ) { - qDebug() << __FUNCTION__ << "Received Data:" << mReceivedData; + emit detailsChanged(); } } @@ -62,5 +56,4 @@ void EgenioussReceiver::onErrorOccurred( QAbstractSocket::SocketError socketErro { mLastError = mTcpSocket->errorString(); emit lastErrorChanged( mLastError ); - qDebug() << __FUNCTION__ << "Socket Error:" << mLastError; } diff --git a/src/core/positioning/positioning.cpp b/src/core/positioning/positioning.cpp index 49d010ad6e..77712b8f0c 100644 --- a/src/core/positioning/positioning.cpp +++ b/src/core/positioning/positioning.cpp @@ -182,6 +182,7 @@ void Positioning::setupDevice() mReceiver->disconnectDevice(); mReceiver->stopLogging(); disconnect( mReceiver, &AbstractGnssReceiver::lastGnssPositionInformationChanged, this, &Positioning::lastGnssPositionInformationChanged ); + disconnect( mReceiver, &AbstractGnssReceiver::detailsChanged, this, &Positioning::detailsChanged ); mReceiver->deleteLater(); mReceiver = nullptr; } @@ -228,6 +229,7 @@ void Positioning::setupDevice() // Reset the position information to insure no cross contamination between receiver types lastGnssPositionInformationChanged( GnssPositionInformation() ); connect( mReceiver, &AbstractGnssReceiver::lastGnssPositionInformationChanged, this, &Positioning::lastGnssPositionInformationChanged ); + connect( mReceiver, &AbstractGnssReceiver::detailsChanged, this, &Positioning::detailsChanged ); setValid( mReceiver->valid() ); emit deviceChanged(); diff --git a/src/core/positioning/positioning.h b/src/core/positioning/positioning.h index 0c8a2ba322..93e5cab59d 100644 --- a/src/core/positioning/positioning.h +++ b/src/core/positioning/positioning.h @@ -201,7 +201,7 @@ class Positioning : public QObject void setLogging( bool logging ); signals: - + void detailsChanged(); void activeChanged(); void deviceIdChanged(); void deviceChanged(); diff --git a/src/core/positioning/positioninginformationmodel.cpp b/src/core/positioning/positioninginformationmodel.cpp index b83f391b7d..aa8654b9d8 100644 --- a/src/core/positioning/positioninginformationmodel.cpp +++ b/src/core/positioning/positioninginformationmodel.cpp @@ -241,6 +241,7 @@ void PositioningInformationModel::setPositioningSource( Positioning *positioning { disconnect( mPositioningSource, &Positioning::positionInformationChanged, this, &PositioningInformationModel::refreshData ); disconnect( mPositioningSource, &Positioning::deviceChanged, this, &PositioningInformationModel::softReset ); + disconnect( mPositioningSource, &Positioning::detailsChanged, this, &PositioningInformationModel::refreshData ); } mPositioningSource = positioningSource; @@ -250,6 +251,7 @@ void PositioningInformationModel::setPositioningSource( Positioning *positioning { connect( mPositioningSource, &Positioning::positionInformationChanged, this, &PositioningInformationModel::refreshData ); connect( mPositioningSource, &Positioning::deviceChanged, this, &PositioningInformationModel::softReset ); + connect( mPositioningSource, &Positioning::detailsChanged, this, &PositioningInformationModel::refreshData ); refreshData(); } } From 084823bf2de6954d07ad85e99bf8188dcf35ff4a Mon Sep 17 00:00:00 2001 From: Mohsen Date: Thu, 12 Sep 2024 15:32:33 +0330 Subject: [PATCH 04/24] Fix ui and try to decode received message. --- src/core/positioning/egenioussreceiver.cpp | 55 +++++++++++++++++++++- src/core/positioning/egenioussreceiver.h | 12 ++++- src/qml/PositioningInformationView.qml | 8 ++-- 3 files changed, 69 insertions(+), 6 deletions(-) diff --git a/src/core/positioning/egenioussreceiver.cpp b/src/core/positioning/egenioussreceiver.cpp index 8500d07c40..8e39149e63 100644 --- a/src/core/positioning/egenioussreceiver.cpp +++ b/src/core/positioning/egenioussreceiver.cpp @@ -39,13 +39,66 @@ void EgenioussReceiver::handleDisconnectDevice() QList> EgenioussReceiver::details() { QList> dataList; - dataList.append( qMakePair( QString( "Egeniouss" ), QVariant::fromValue( mReceivedData ) ) ); + dataList.append( qMakePair( QString( "startByte" ), QString::number( startByte ) ) ); + dataList.append( qMakePair( QString( "protocolVersion" ), QString::number( protocolVersion ) ) ); + dataList.append( qMakePair( QString( "counter" ), QString::number( counter ) ) ); + dataList.append( qMakePair( QString( "messageId" ), QString::number( messageId ) ) ); + dataList.append( qMakePair( QString( "N" ), QString::number( N ) ) ); + dataList.append( qMakePair( QString( "Payload" ), QVariant::fromValue( payload.toHex() ) ) ); return dataList; } +void EgenioussReceiver::processReceivedData() +{ + // Check if the received data is long enough + if ( mReceivedData.size() < 9 ) + { + qDebug() << "Received data is too short to process."; + return; + } + + // Read the start byte (uint8) + startByte = static_cast( mReceivedData[0] ); + if ( startByte != 0xFE ) + { + qDebug() << "Invalid start byte:" << startByte; + return; + } + + // Read the next bytes (uint8s) + protocolVersion = static_cast( mReceivedData[1] ); + counter = static_cast( mReceivedData[2] ); + messageId = static_cast( mReceivedData[3] ); + + // Read the N value (uint32) + N = 0; + if ( mReceivedData.size() < 9 + sizeof( uint32_t ) ) + { + qDebug() << "Received data is too short to read N."; + return; + } + + // Convert bytes 4 to 8 into a uint32 + QDataStream dataStream( mReceivedData.mid( 4, 4 ) ); + dataStream.setByteOrder( QDataStream::LittleEndian ); // Make sure the byte order matches protocol + dataStream >> N; + + // Check if we have enough payload data + if ( mReceivedData.size() < 9 + N ) + { + qDebug() << "Received data is too short to contain the payload."; + return; + } + + // Extract the payload + payload = mReceivedData.mid( 8, N ); +} void EgenioussReceiver::onReadyRead() { mReceivedData = mTcpSocket->readAll(); + + processReceivedData(); + if ( valid() ) { emit detailsChanged(); diff --git a/src/core/positioning/egenioussreceiver.h b/src/core/positioning/egenioussreceiver.h index 980d8cadfd..3ba3427eee 100644 --- a/src/core/positioning/egenioussreceiver.h +++ b/src/core/positioning/egenioussreceiver.h @@ -20,7 +20,17 @@ class EgenioussReceiver : public AbstractGnssReceiver void onReadyRead(); void onErrorOccurred( QAbstractSocket::SocketError socketError ); + private: + void processReceivedData(); + private: QTcpSocket *mTcpSocket = nullptr; - QString mReceivedData; + QByteArray mReceivedData; + + uint8_t startByte; + uint8_t protocolVersion; + uint8_t counter; + uint8_t messageId; + uint32_t N; + QByteArray payload; }; 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 From 76963a1fd3321f8ba39b654fc4d31342afa7092e Mon Sep 17 00:00:00 2001 From: Mohsen Date: Thu, 12 Sep 2024 20:04:11 +0330 Subject: [PATCH 05/24] Read payload. assuming payload is a json. (right?) --- src/core/positioning/egenioussreceiver.cpp | 36 ++++++++++++---------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/src/core/positioning/egenioussreceiver.cpp b/src/core/positioning/egenioussreceiver.cpp index 8e39149e63..bab3815e0e 100644 --- a/src/core/positioning/egenioussreceiver.cpp +++ b/src/core/positioning/egenioussreceiver.cpp @@ -1,6 +1,9 @@ #include "egenioussreceiver.h" #include +#include +#include +#include EgenioussReceiver::EgenioussReceiver( QObject *parent ) : AbstractGnssReceiver( parent ), mTcpSocket( new QTcpSocket( this ) ) @@ -44,20 +47,33 @@ QList> EgenioussReceiver::details() dataList.append( qMakePair( QString( "counter" ), QString::number( counter ) ) ); dataList.append( qMakePair( QString( "messageId" ), QString::number( messageId ) ) ); dataList.append( qMakePair( QString( "N" ), QString::number( N ) ) ); - dataList.append( qMakePair( QString( "Payload" ), QVariant::fromValue( payload.toHex() ) ) ); + + QJsonDocument jsonDoc = QJsonDocument::fromJson( payload ); + if ( jsonDoc.isNull() || !jsonDoc.isObject() ) + { + qWarning() << "Failed to parse JSON:"; + return dataList; + } + + QJsonObject jsonObject = jsonDoc.object(); + + for ( auto it = jsonObject.begin(); it != jsonObject.end(); ++it ) + { + QString key = it.key(); + QVariant value = it.value().toVariant(); + dataList.append( qMakePair( key, value ) ); + } return dataList; } void EgenioussReceiver::processReceivedData() { - // Check if the received data is long enough if ( mReceivedData.size() < 9 ) { qDebug() << "Received data is too short to process."; return; } - // Read the start byte (uint8) startByte = static_cast( mReceivedData[0] ); if ( startByte != 0xFE ) { @@ -65,32 +81,20 @@ void EgenioussReceiver::processReceivedData() return; } - // Read the next bytes (uint8s) protocolVersion = static_cast( mReceivedData[1] ); counter = static_cast( mReceivedData[2] ); messageId = static_cast( mReceivedData[3] ); - // Read the N value (uint32) - N = 0; - if ( mReceivedData.size() < 9 + sizeof( uint32_t ) ) - { - qDebug() << "Received data is too short to read N."; - return; - } - - // Convert bytes 4 to 8 into a uint32 QDataStream dataStream( mReceivedData.mid( 4, 4 ) ); dataStream.setByteOrder( QDataStream::LittleEndian ); // Make sure the byte order matches protocol dataStream >> N; - // Check if we have enough payload data - if ( mReceivedData.size() < 9 + N ) + if ( mReceivedData.size() < 8 + N ) { qDebug() << "Received data is too short to contain the payload."; return; } - // Extract the payload payload = mReceivedData.mid( 8, N ); } void EgenioussReceiver::onReadyRead() From 2009f8782877ccecbdebe1aa11ac6293d7980d26 Mon Sep 17 00:00:00 2001 From: Mohsen Date: Fri, 13 Sep 2024 10:19:22 +0330 Subject: [PATCH 06/24] Remove detailsChanged signal and use positionInformationChanged. No need for detailsChanged. --- src/core/positioning/abstractgnssreceiver.h | 1 - src/core/positioning/egenioussreceiver.cpp | 83 ++++++++----------- src/core/positioning/egenioussreceiver.h | 7 +- src/core/positioning/positioning.cpp | 2 - src/core/positioning/positioning.h | 1 - .../positioninginformationmodel.cpp | 2 - 6 files changed, 36 insertions(+), 60 deletions(-) diff --git a/src/core/positioning/abstractgnssreceiver.h b/src/core/positioning/abstractgnssreceiver.h index 6fdde7bbd1..0688ea1e03 100644 --- a/src/core/positioning/abstractgnssreceiver.h +++ b/src/core/positioning/abstractgnssreceiver.h @@ -64,7 +64,6 @@ class AbstractGnssReceiver : public QObject virtual QList> details() { return {}; } signals: - void detailsChanged(); void validChanged(); void lastGnssPositionInformationChanged( GnssPositionInformation &lastGnssPositionInformation ); void socketStateChanged( QAbstractSocket::SocketState socketState ); diff --git a/src/core/positioning/egenioussreceiver.cpp b/src/core/positioning/egenioussreceiver.cpp index bab3815e0e..455a1dee32 100644 --- a/src/core/positioning/egenioussreceiver.cpp +++ b/src/core/positioning/egenioussreceiver.cpp @@ -42,70 +42,57 @@ void EgenioussReceiver::handleDisconnectDevice() QList> EgenioussReceiver::details() { QList> dataList; - dataList.append( qMakePair( QString( "startByte" ), QString::number( startByte ) ) ); - dataList.append( qMakePair( QString( "protocolVersion" ), QString::number( protocolVersion ) ) ); - dataList.append( qMakePair( QString( "counter" ), QString::number( counter ) ) ); - dataList.append( qMakePair( QString( "messageId" ), QString::number( messageId ) ) ); - dataList.append( qMakePair( QString( "N" ), QString::number( N ) ) ); QJsonDocument jsonDoc = QJsonDocument::fromJson( payload ); - if ( jsonDoc.isNull() || !jsonDoc.isObject() ) - { - qWarning() << "Failed to parse JSON:"; - return dataList; - } - QJsonObject jsonObject = jsonDoc.object(); - for ( auto it = jsonObject.begin(); it != jsonObject.end(); ++it ) - { - QString key = it.key(); - QVariant value = it.value().toVariant(); - dataList.append( qMakePair( key, value ) ); - } + dataList.append( qMakePair( "q", jsonObject.value( "q" ).toString() ) ); + return dataList; } -void EgenioussReceiver::processReceivedData() +void EgenioussReceiver::onReadyRead() { - if ( mReceivedData.size() < 9 ) + if ( valid() ) { - qDebug() << "Received data is too short to process."; - return; - } + mReceivedData = mTcpSocket->readAll(); + if ( mReceivedData.size() < 9 ) + { + return; // Received data is too short to process. + } - startByte = static_cast( mReceivedData[0] ); - if ( startByte != 0xFE ) - { - qDebug() << "Invalid start byte:" << startByte; - return; - } + if ( static_cast( mReceivedData[0] ) != 0xFE ) + { + return; // Invalid start byte + } - protocolVersion = static_cast( mReceivedData[1] ); - counter = static_cast( mReceivedData[2] ); - messageId = static_cast( mReceivedData[3] ); + uint32_t payloadLength; + QDataStream dataStream( mReceivedData.mid( 4, 4 ) ); + dataStream.setByteOrder( QDataStream::LittleEndian ); + dataStream >> payloadLength; - QDataStream dataStream( mReceivedData.mid( 4, 4 ) ); - dataStream.setByteOrder( QDataStream::LittleEndian ); // Make sure the byte order matches protocol - dataStream >> N; + if ( mReceivedData.size() < 8 + payloadLength ) + { + return; // Received data is too short to contain the payload. + } - if ( mReceivedData.size() < 8 + N ) - { - qDebug() << "Received data is too short to contain the payload."; - return; - } + payload = mReceivedData.mid( 8, payloadLength ); - payload = mReceivedData.mid( 8, N ); -} -void EgenioussReceiver::onReadyRead() -{ - mReceivedData = mTcpSocket->readAll(); + QJsonDocument jsonDoc = QJsonDocument::fromJson( payload ); - processReceivedData(); + if ( jsonDoc.isNull() || !jsonDoc.isObject() ) + { + return; // Failed to parse JSON + } - if ( valid() ) - { - emit detailsChanged(); + QJsonObject jsonObject = jsonDoc.object(); + + mLastGnssPositionInformation = GnssPositionInformation( + jsonObject.value( "lat" ).toDouble(), + jsonObject.value( "lon" ).toDouble(), + jsonObject.value( "alt" ).toDouble() ); + + emit lastGnssPositionInformationChanged( mLastGnssPositionInformation ); } } diff --git a/src/core/positioning/egenioussreceiver.h b/src/core/positioning/egenioussreceiver.h index 3ba3427eee..8cc1e40a4d 100644 --- a/src/core/positioning/egenioussreceiver.h +++ b/src/core/positioning/egenioussreceiver.h @@ -25,12 +25,7 @@ class EgenioussReceiver : public AbstractGnssReceiver private: QTcpSocket *mTcpSocket = nullptr; + GnssPositionInformation mLastGnssPositionInformation; QByteArray mReceivedData; - - uint8_t startByte; - uint8_t protocolVersion; - uint8_t counter; - uint8_t messageId; - uint32_t N; QByteArray payload; }; diff --git a/src/core/positioning/positioning.cpp b/src/core/positioning/positioning.cpp index 77712b8f0c..49d010ad6e 100644 --- a/src/core/positioning/positioning.cpp +++ b/src/core/positioning/positioning.cpp @@ -182,7 +182,6 @@ void Positioning::setupDevice() mReceiver->disconnectDevice(); mReceiver->stopLogging(); disconnect( mReceiver, &AbstractGnssReceiver::lastGnssPositionInformationChanged, this, &Positioning::lastGnssPositionInformationChanged ); - disconnect( mReceiver, &AbstractGnssReceiver::detailsChanged, this, &Positioning::detailsChanged ); mReceiver->deleteLater(); mReceiver = nullptr; } @@ -229,7 +228,6 @@ void Positioning::setupDevice() // Reset the position information to insure no cross contamination between receiver types lastGnssPositionInformationChanged( GnssPositionInformation() ); connect( mReceiver, &AbstractGnssReceiver::lastGnssPositionInformationChanged, this, &Positioning::lastGnssPositionInformationChanged ); - connect( mReceiver, &AbstractGnssReceiver::detailsChanged, this, &Positioning::detailsChanged ); setValid( mReceiver->valid() ); emit deviceChanged(); diff --git a/src/core/positioning/positioning.h b/src/core/positioning/positioning.h index 93e5cab59d..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 detailsChanged(); void activeChanged(); void deviceIdChanged(); void deviceChanged(); diff --git a/src/core/positioning/positioninginformationmodel.cpp b/src/core/positioning/positioninginformationmodel.cpp index aa8654b9d8..b83f391b7d 100644 --- a/src/core/positioning/positioninginformationmodel.cpp +++ b/src/core/positioning/positioninginformationmodel.cpp @@ -241,7 +241,6 @@ void PositioningInformationModel::setPositioningSource( Positioning *positioning { disconnect( mPositioningSource, &Positioning::positionInformationChanged, this, &PositioningInformationModel::refreshData ); disconnect( mPositioningSource, &Positioning::deviceChanged, this, &PositioningInformationModel::softReset ); - disconnect( mPositioningSource, &Positioning::detailsChanged, this, &PositioningInformationModel::refreshData ); } mPositioningSource = positioningSource; @@ -251,7 +250,6 @@ void PositioningInformationModel::setPositioningSource( Positioning *positioning { connect( mPositioningSource, &Positioning::positionInformationChanged, this, &PositioningInformationModel::refreshData ); connect( mPositioningSource, &Positioning::deviceChanged, this, &PositioningInformationModel::softReset ); - connect( mPositioningSource, &Positioning::detailsChanged, this, &PositioningInformationModel::refreshData ); refreshData(); } } From 7d9a9bcc2af85f2577d3bcd449dddb3ad7bf186e Mon Sep 17 00:00:00 2001 From: Mohsen Date: Fri, 13 Sep 2024 10:37:19 +0330 Subject: [PATCH 07/24] Set quality to 1 to pass `mPositionInformation.isValid()` condition. --- src/core/positioning/egenioussreceiver.cpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/core/positioning/egenioussreceiver.cpp b/src/core/positioning/egenioussreceiver.cpp index 455a1dee32..2ca92fb791 100644 --- a/src/core/positioning/egenioussreceiver.cpp +++ b/src/core/positioning/egenioussreceiver.cpp @@ -90,7 +90,19 @@ void EgenioussReceiver::onReadyRead() mLastGnssPositionInformation = GnssPositionInformation( jsonObject.value( "lat" ).toDouble(), jsonObject.value( "lon" ).toDouble(), - jsonObject.value( "alt" ).toDouble() ); + jsonObject.value( "alt" ).toDouble(), + 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(), + QChar(), + 0, + 1 ); emit lastGnssPositionInformationChanged( mLastGnssPositionInformation ); } From 089b1dafeea660cdeb9b0dfd338832729787be3c Mon Sep 17 00:00:00 2001 From: Mohsen Date: Fri, 13 Sep 2024 11:58:32 +0330 Subject: [PATCH 08/24] Try to set utc and fix crash on android. I hope sent utc is millisecond :) --- src/core/positioning/egenioussreceiver.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/core/positioning/egenioussreceiver.cpp b/src/core/positioning/egenioussreceiver.cpp index 2ca92fb791..81c732954f 100644 --- a/src/core/positioning/egenioussreceiver.cpp +++ b/src/core/positioning/egenioussreceiver.cpp @@ -8,12 +8,13 @@ EgenioussReceiver::EgenioussReceiver( QObject *parent ) : AbstractGnssReceiver( parent ), mTcpSocket( new QTcpSocket( this ) ) { - connect( mTcpSocket, &QTcpSocket::readyRead, this, &EgenioussReceiver::onReadyRead ); - connect( mTcpSocket, &QTcpSocket::errorOccurred, this, &EgenioussReceiver::onErrorOccurred ); } void EgenioussReceiver::handleConnectDevice() { + connect( mTcpSocket, &QTcpSocket::readyRead, this, &EgenioussReceiver::onReadyRead ); + connect( mTcpSocket, &QTcpSocket::errorOccurred, this, &EgenioussReceiver::onErrorOccurred ); + mTcpSocket->connectToHost( QHostAddress::LocalHost, 1235 ); if ( !mTcpSocket->waitForConnected( 3000 ) ) @@ -32,6 +33,9 @@ void EgenioussReceiver::handleConnectDevice() void EgenioussReceiver::handleDisconnectDevice() { + disconnect( mTcpSocket, &QTcpSocket::readyRead, this, &EgenioussReceiver::onReadyRead ); + disconnect( mTcpSocket, &QTcpSocket::errorOccurred, this, &EgenioussReceiver::onErrorOccurred ); + if ( mTcpSocket->state() == QAbstractSocket::ConnectedState ) { mTcpSocket->disconnectFromHost(); @@ -47,6 +51,8 @@ QList> EgenioussReceiver::details() QJsonObject jsonObject = jsonDoc.object(); dataList.append( qMakePair( "q", jsonObject.value( "q" ).toString() ) ); + dataList.append( qMakePair( "utc", jsonObject.value( "utc" ).toDouble() ) ); + dataList.append( qMakePair( "utc convert", QDateTime( QDateTime::fromMSecsSinceEpoch( jsonObject.value( "utc" ).toDouble(), Qt::UTC ) ).toString() ) ); return dataList; } @@ -99,7 +105,7 @@ void EgenioussReceiver::onReadyRead() 0, std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN(), - QDateTime(), + QDateTime::fromMSecsSinceEpoch( jsonObject.value( "utc" ).toDouble(), Qt::UTC ), QChar(), 0, 1 ); From ee635cfa82ba54878ede3ac8fd665eb7fd57d4c9 Mon Sep 17 00:00:00 2001 From: Mohsen Date: Fri, 13 Sep 2024 12:53:03 +0330 Subject: [PATCH 09/24] Nanosecond utc + Connect address and port from ui. Can we merge deviceChoosers ? TCP, UDP, Egeniouss? I'll revert QHostAddress::LocalHost later. --- src/core/positioning/egenioussreceiver.cpp | 15 +++-- src/core/positioning/egenioussreceiver.h | 4 +- src/core/positioning/positioning.cpp | 12 ++-- .../positioning/positioningdevicemodel.cpp | 2 +- src/qml/EgenioussDeviceChooser.qml | 65 +++++++++++++++++++ src/qml/PositioningDeviceSettings.qml | 2 +- src/qml/qml.qrc | 1 + 7 files changed, 85 insertions(+), 16 deletions(-) create mode 100644 src/qml/EgenioussDeviceChooser.qml diff --git a/src/core/positioning/egenioussreceiver.cpp b/src/core/positioning/egenioussreceiver.cpp index 81c732954f..d39d279f12 100644 --- a/src/core/positioning/egenioussreceiver.cpp +++ b/src/core/positioning/egenioussreceiver.cpp @@ -5,8 +5,8 @@ #include #include -EgenioussReceiver::EgenioussReceiver( QObject *parent ) - : AbstractGnssReceiver( parent ), mTcpSocket( new QTcpSocket( this ) ) +EgenioussReceiver::EgenioussReceiver( const QString &address, const int port, QObject *parent ) + : AbstractGnssReceiver( parent ), mAddress( address ), mPort( port ), mTcpSocket( new QTcpSocket( this ) ) { } @@ -15,7 +15,7 @@ void EgenioussReceiver::handleConnectDevice() connect( mTcpSocket, &QTcpSocket::readyRead, this, &EgenioussReceiver::onReadyRead ); connect( mTcpSocket, &QTcpSocket::errorOccurred, this, &EgenioussReceiver::onErrorOccurred ); - mTcpSocket->connectToHost( QHostAddress::LocalHost, 1235 ); + mTcpSocket->connectToHost( QHostAddress::LocalHost, mPort ); if ( !mTcpSocket->waitForConnected( 3000 ) ) { @@ -50,9 +50,12 @@ QList> EgenioussReceiver::details() QJsonDocument jsonDoc = QJsonDocument::fromJson( payload ); QJsonObject jsonObject = jsonDoc.object(); + if ( jsonDoc.isNull() || !jsonDoc.isObject() ) + { + return dataList; // Failed to parse JSON + } + dataList.append( qMakePair( "q", jsonObject.value( "q" ).toString() ) ); - dataList.append( qMakePair( "utc", jsonObject.value( "utc" ).toDouble() ) ); - dataList.append( qMakePair( "utc convert", QDateTime( QDateTime::fromMSecsSinceEpoch( jsonObject.value( "utc" ).toDouble(), Qt::UTC ) ).toString() ) ); return dataList; } @@ -105,7 +108,7 @@ void EgenioussReceiver::onReadyRead() 0, std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN(), - QDateTime::fromMSecsSinceEpoch( jsonObject.value( "utc" ).toDouble(), Qt::UTC ), + QDateTime::fromMSecsSinceEpoch( jsonObject.value( "utc" ).toDouble() / 1e6, Qt::UTC ), QChar(), 0, 1 ); diff --git a/src/core/positioning/egenioussreceiver.h b/src/core/positioning/egenioussreceiver.h index 8cc1e40a4d..73f5f83b35 100644 --- a/src/core/positioning/egenioussreceiver.h +++ b/src/core/positioning/egenioussreceiver.h @@ -9,7 +9,7 @@ class EgenioussReceiver : public AbstractGnssReceiver Q_OBJECT public: - explicit EgenioussReceiver( QObject *parent = nullptr ); + explicit EgenioussReceiver( const QString &address = QString(), const int port = 0, QObject *parent = nullptr ); private: void handleConnectDevice() override; @@ -25,6 +25,8 @@ class EgenioussReceiver : public AbstractGnssReceiver private: QTcpSocket *mTcpSocket = nullptr; + QString mAddress; + int mPort = 0; GnssPositionInformation mLastGnssPositionInformation; QByteArray mReceivedData; QByteArray payload; diff --git a/src/core/positioning/positioning.cpp b/src/core/positioning/positioning.cpp index 49d010ad6e..4f427ea11d 100644 --- a/src/core/positioning/positioning.cpp +++ b/src/core/positioning/positioning.cpp @@ -192,23 +192,21 @@ void Positioning::setupDevice() } else { + const qsizetype portSeparator = mDeviceId.lastIndexOf( ':' ); + const QString address = mDeviceId.mid( 4, portSeparator - 4 ); + const int port = mDeviceId.mid( portSeparator + 1 ).toInt(); + if ( mDeviceId.startsWith( QStringLiteral( "tcp:" ) ) ) { - const qsizetype portSeparator = mDeviceId.lastIndexOf( ':' ); - const QString address = mDeviceId.mid( 4, portSeparator - 4 ); - const int port = mDeviceId.mid( portSeparator + 1 ).toInt(); mReceiver = new TcpReceiver( address, port, this ); } else if ( mDeviceId.startsWith( QStringLiteral( "udp:" ) ) ) { - const qsizetype portSeparator = mDeviceId.lastIndexOf( ':' ); - const QString address = mDeviceId.mid( 4, portSeparator - 4 ); - const int port = mDeviceId.mid( portSeparator + 1 ).toInt(); mReceiver = new UdpReceiver( address, port, this ); } else if ( mDeviceId.startsWith( QStringLiteral( "egeniouss:" ) ) ) { - mReceiver = new EgenioussReceiver( this ); + mReceiver = new EgenioussReceiver( address, port, this ); } #ifdef WITH_SERIALPORT else if ( mDeviceId.startsWith( QStringLiteral( "serial:" ) ) ) diff --git a/src/core/positioning/positioningdevicemodel.cpp b/src/core/positioning/positioningdevicemodel.cpp index f4577cdf6f..17eb82a612 100644 --- a/src/core/positioning/positioningdevicemodel.cpp +++ b/src/core/positioning/positioningdevicemodel.cpp @@ -173,7 +173,7 @@ const QString PositioningDeviceModel::deviceId( const Device &device ) const return QStringLiteral( "serial:%1" ).arg( device.settings.value( QStringLiteral( "address" ) ).toString() ); case EgenioussDevice: - return QStringLiteral( "egeniouss:%1" ).arg( device.settings.value( QStringLiteral( "address" ) ).toString() ); + return QStringLiteral( "egeniouss:%1:%2" ).arg( device.settings.value( QStringLiteral( "address" ) ).toString(), QString::number( device.settings.value( QStringLiteral( "port" ) ).toInt() ) ); } return QString(); diff --git a/src/qml/EgenioussDeviceChooser.qml b/src/qml/EgenioussDeviceChooser.qml new file mode 100644 index 0000000000..1f02442abb --- /dev/null +++ b/src/qml/EgenioussDeviceChooser.qml @@ -0,0 +1,65 @@ +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import org.qfield +import Theme + +Item { + width: parent.width + + property alias deviceAddress: egenioussDeviceAddress.text + property alias devicePort: egenioussDevicePort.text + + function generateName() { + return deviceAddress + ' (' + devicePort + ')'; + } + + function setSettings(settings) { + deviceAddress = settings['address']; + devicePort = settings['port']; + } + + function getSettings() { + return { + "address": deviceAddress.trim(), + "port": parseInt(devicePort) + }; + } + + GridLayout { + width: parent.width + columns: 1 + columnSpacing: 0 + rowSpacing: 5 + + Label { + Layout.fillWidth: true + text: qsTr("Address:") + font: Theme.defaultFont + wrapMode: Text.WordWrap + } + + QfTextField { + id: egenioussDeviceAddress + Layout.fillWidth: true + font: Theme.defaultFont + text: '127.0.0.1' + inputMethodHints: Qt.ImhNoPredictiveText | Qt.ImhNoAutoUppercase | Qt.ImhPreferLowercase + } + + Label { + Layout.fillWidth: true + text: qsTr("Port:") + font: Theme.defaultFont + wrapMode: Text.WordWrap + } + + QfTextField { + id: egenioussDevicePort + Layout.fillWidth: true + font: Theme.defaultFont + text: '1235' + inputMethodHints: Qt.ImhFormattedNumbersOnly + } + } +} diff --git a/src/qml/PositioningDeviceSettings.qml b/src/qml/PositioningDeviceSettings.qml index 30d80ba454..b10685c391 100644 --- a/src/qml/PositioningDeviceSettings.qml +++ b/src/qml/PositioningDeviceSettings.qml @@ -202,7 +202,7 @@ Popup { case PositioningDeviceModel.SerialPortDevice: return "qrc:/qml/SerialPortDeviceChooser.qml"; case PositioningDeviceModel.EgenioussDevice: - return "qrc:/qml/TcpDeviceChooser.qml"; + return "qrc:/qml/EgenioussDeviceChooser.qml"; } return ''; } 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 From 817566a6274f64e2292f8b914aad00846b4d2d15 Mon Sep 17 00:00:00 2001 From: Mohsen Date: Fri, 13 Sep 2024 21:01:39 +0330 Subject: [PATCH 10/24] Try to use mAddress instead of localhost. --- src/core/positioning/egenioussreceiver.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/core/positioning/egenioussreceiver.cpp b/src/core/positioning/egenioussreceiver.cpp index d39d279f12..a6f158a03b 100644 --- a/src/core/positioning/egenioussreceiver.cpp +++ b/src/core/positioning/egenioussreceiver.cpp @@ -8,6 +8,7 @@ EgenioussReceiver::EgenioussReceiver( const QString &address, const int port, QObject *parent ) : AbstractGnssReceiver( parent ), mAddress( address ), mPort( port ), mTcpSocket( new QTcpSocket( this ) ) { + setValid( !mAddress.isEmpty() && mPort > 0 ); } void EgenioussReceiver::handleConnectDevice() @@ -15,17 +16,20 @@ void EgenioussReceiver::handleConnectDevice() connect( mTcpSocket, &QTcpSocket::readyRead, this, &EgenioussReceiver::onReadyRead ); connect( mTcpSocket, &QTcpSocket::errorOccurred, this, &EgenioussReceiver::onErrorOccurred ); - mTcpSocket->connectToHost( QHostAddress::LocalHost, mPort ); + if ( mAddress.isEmpty() || mPort == 0 ) + { + return; + } + + mTcpSocket->connectToHost( QHostAddress( mAddress ), mPort, QTcpSocket::ReadWrite ); if ( !mTcpSocket->waitForConnected( 3000 ) ) { - setValid( false ); mLastError = mTcpSocket->errorString(); emit lastErrorChanged( mLastError ); } else { - setValid( true ); mSocketState = QAbstractSocket::ConnectedState; emit socketStateChanged( mSocketState ); } From be89cc572d97450fb8a76cc6d115f5162d5dc8de Mon Sep 17 00:00:00 2001 From: Mohsen Date: Sat, 14 Sep 2024 19:42:27 +0330 Subject: [PATCH 11/24] Address review - part 1. --- src/core/positioning/egenioussreceiver.cpp | 151 +++++++++------------ src/core/positioning/egenioussreceiver.h | 13 +- src/core/positioning/positioning.cpp | 12 +- 3 files changed, 79 insertions(+), 97 deletions(-) diff --git a/src/core/positioning/egenioussreceiver.cpp b/src/core/positioning/egenioussreceiver.cpp index a6f158a03b..db9bdfb9ba 100644 --- a/src/core/positioning/egenioussreceiver.cpp +++ b/src/core/positioning/egenioussreceiver.cpp @@ -2,123 +2,102 @@ #include #include -#include #include -EgenioussReceiver::EgenioussReceiver( const QString &address, const int port, QObject *parent ) - : AbstractGnssReceiver( parent ), mAddress( address ), mPort( port ), mTcpSocket( new QTcpSocket( this ) ) +EgenioussReceiver::EgenioussReceiver( QObject *parent ) + : AbstractGnssReceiver( parent ), mTcpSocket( new QTcpSocket( this ) ) { - setValid( !mAddress.isEmpty() && mPort > 0 ); + connect( mTcpSocket, &QTcpSocket::readyRead, this, &EgenioussReceiver::onReadyRead ); + connect( mTcpSocket, &QTcpSocket::errorOccurred, this, &EgenioussReceiver::onErrorOccurred ); + connect( mTcpSocket, &QTcpSocket::connected, this, &EgenioussReceiver::connected ); + connect( mTcpSocket, &QTcpSocket::disconnected, this, &EgenioussReceiver::disconnected ); } void EgenioussReceiver::handleConnectDevice() { - connect( mTcpSocket, &QTcpSocket::readyRead, this, &EgenioussReceiver::onReadyRead ); - connect( mTcpSocket, &QTcpSocket::errorOccurred, this, &EgenioussReceiver::onErrorOccurred ); - - if ( mAddress.isEmpty() || mPort == 0 ) - { - return; - } - - mTcpSocket->connectToHost( QHostAddress( mAddress ), mPort, QTcpSocket::ReadWrite ); + mTcpSocket->connectToHost( mAddress, mPort, QTcpSocket::ReadWrite ); +} - if ( !mTcpSocket->waitForConnected( 3000 ) ) - { - mLastError = mTcpSocket->errorString(); - emit lastErrorChanged( mLastError ); - } - else - { - mSocketState = QAbstractSocket::ConnectedState; - emit socketStateChanged( mSocketState ); - } +void EgenioussReceiver::connected() +{ + mSocketState = QAbstractSocket::ConnectedState; + emit socketStateChanged( mSocketState ); } void EgenioussReceiver::handleDisconnectDevice() { - disconnect( mTcpSocket, &QTcpSocket::readyRead, this, &EgenioussReceiver::onReadyRead ); - disconnect( mTcpSocket, &QTcpSocket::errorOccurred, this, &EgenioussReceiver::onErrorOccurred ); + mTcpSocket->disconnectFromHost(); +} +void EgenioussReceiver::disconnected() +{ if ( mTcpSocket->state() == QAbstractSocket::ConnectedState ) { - mTcpSocket->disconnectFromHost(); - mTcpSocket->waitForDisconnected(); + mSocketState = QAbstractSocket::UnconnectedState; + emit socketStateChanged( mSocketState ); } } QList> EgenioussReceiver::details() { - QList> dataList; + QList> detailsList; - QJsonDocument jsonDoc = QJsonDocument::fromJson( payload ); - QJsonObject jsonObject = jsonDoc.object(); - - if ( jsonDoc.isNull() || !jsonDoc.isObject() ) + if ( mPayload.isEmpty() ) { - return dataList; // Failed to parse JSON + return detailsList; } - dataList.append( qMakePair( "q", jsonObject.value( "q" ).toString() ) ); + detailsList.append( qMakePair( "q", mPayload.value( "q" ).toString() ) ); - return dataList; + return detailsList; } void EgenioussReceiver::onReadyRead() { - if ( valid() ) + QByteArray mReceivedData = mTcpSocket->readAll(); + if ( mReceivedData.size() < 9 ) { - mReceivedData = mTcpSocket->readAll(); - if ( mReceivedData.size() < 9 ) - { - return; // Received data is too short to process. - } - - if ( static_cast( mReceivedData[0] ) != 0xFE ) - { - return; // Invalid start byte - } - - uint32_t payloadLength; - QDataStream dataStream( mReceivedData.mid( 4, 4 ) ); - dataStream.setByteOrder( QDataStream::LittleEndian ); - dataStream >> payloadLength; - - if ( mReceivedData.size() < 8 + payloadLength ) - { - return; // Received data is too short to contain the payload. - } - - payload = mReceivedData.mid( 8, payloadLength ); - - QJsonDocument jsonDoc = QJsonDocument::fromJson( payload ); - - if ( jsonDoc.isNull() || !jsonDoc.isObject() ) - { - return; // Failed to parse JSON - } - - QJsonObject jsonObject = jsonDoc.object(); - - mLastGnssPositionInformation = GnssPositionInformation( - jsonObject.value( "lat" ).toDouble(), - jsonObject.value( "lon" ).toDouble(), - jsonObject.value( "alt" ).toDouble(), - 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( jsonObject.value( "utc" ).toDouble() / 1e6, Qt::UTC ), - QChar(), - 0, - 1 ); - - emit lastGnssPositionInformationChanged( mLastGnssPositionInformation ); + return; // Received data is too short to process. + } + if ( static_cast( mReceivedData[0] ) != 0xFE ) + { + return; // Invalid start byte + } + uint32_t payloadLength; + QDataStream dataStream( mReceivedData.mid( 4, 4 ) ); + dataStream.setByteOrder( QDataStream::LittleEndian ); + dataStream >> payloadLength; + if ( mReceivedData.size() < 8 + payloadLength ) + { + return; // Received data is too short to contain the payload. + } + QJsonDocument jsonDoc = QJsonDocument::fromJson( mReceivedData.mid( 8, payloadLength ) ); + if ( jsonDoc.isNull() || !jsonDoc.isObject() ) + { + return; // Failed to parse JSON } + 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::onErrorOccurred( QAbstractSocket::SocketError socketError ) diff --git a/src/core/positioning/egenioussreceiver.h b/src/core/positioning/egenioussreceiver.h index 73f5f83b35..724e48a4cd 100644 --- a/src/core/positioning/egenioussreceiver.h +++ b/src/core/positioning/egenioussreceiver.h @@ -2,6 +2,7 @@ #include "abstractgnssreceiver.h" +#include #include class EgenioussReceiver : public AbstractGnssReceiver @@ -9,7 +10,7 @@ class EgenioussReceiver : public AbstractGnssReceiver Q_OBJECT public: - explicit EgenioussReceiver( const QString &address = QString(), const int port = 0, QObject *parent = nullptr ); + explicit EgenioussReceiver( QObject *parent = nullptr ); private: void handleConnectDevice() override; @@ -22,12 +23,12 @@ class EgenioussReceiver : public AbstractGnssReceiver private: void processReceivedData(); + void connected(); + void disconnected(); private: QTcpSocket *mTcpSocket = nullptr; - QString mAddress; - int mPort = 0; - GnssPositionInformation mLastGnssPositionInformation; - QByteArray mReceivedData; - QByteArray payload; + QJsonObject mPayload; + const QHostAddress::SpecialAddress mAddress = QHostAddress::LocalHost; + const int mPort = 1235; }; diff --git a/src/core/positioning/positioning.cpp b/src/core/positioning/positioning.cpp index 4f427ea11d..49d010ad6e 100644 --- a/src/core/positioning/positioning.cpp +++ b/src/core/positioning/positioning.cpp @@ -192,21 +192,23 @@ void Positioning::setupDevice() } else { - const qsizetype portSeparator = mDeviceId.lastIndexOf( ':' ); - const QString address = mDeviceId.mid( 4, portSeparator - 4 ); - const int port = mDeviceId.mid( portSeparator + 1 ).toInt(); - if ( mDeviceId.startsWith( QStringLiteral( "tcp:" ) ) ) { + const qsizetype portSeparator = mDeviceId.lastIndexOf( ':' ); + const QString address = mDeviceId.mid( 4, portSeparator - 4 ); + const int port = mDeviceId.mid( portSeparator + 1 ).toInt(); mReceiver = new TcpReceiver( address, port, this ); } else if ( mDeviceId.startsWith( QStringLiteral( "udp:" ) ) ) { + const qsizetype portSeparator = mDeviceId.lastIndexOf( ':' ); + const QString address = mDeviceId.mid( 4, portSeparator - 4 ); + const int port = mDeviceId.mid( portSeparator + 1 ).toInt(); mReceiver = new UdpReceiver( address, port, this ); } else if ( mDeviceId.startsWith( QStringLiteral( "egeniouss:" ) ) ) { - mReceiver = new EgenioussReceiver( address, port, this ); + mReceiver = new EgenioussReceiver( this ); } #ifdef WITH_SERIALPORT else if ( mDeviceId.startsWith( QStringLiteral( "serial:" ) ) ) From 661a6233e6775a2e7dd02db3fed278d94477c01d Mon Sep 17 00:00:00 2001 From: Mohsen Date: Sat, 14 Sep 2024 20:34:19 +0330 Subject: [PATCH 12/24] Address review - part 2. --- src/core/positioning/egenioussreceiver.cpp | 3 ++- src/core/positioning/egenioussreceiver.h | 5 ++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/core/positioning/egenioussreceiver.cpp b/src/core/positioning/egenioussreceiver.cpp index db9bdfb9ba..5d002953d6 100644 --- a/src/core/positioning/egenioussreceiver.cpp +++ b/src/core/positioning/egenioussreceiver.cpp @@ -22,6 +22,7 @@ void EgenioussReceiver::connected() { mSocketState = QAbstractSocket::ConnectedState; emit socketStateChanged( mSocketState ); + setValid( true ); } void EgenioussReceiver::handleDisconnectDevice() @@ -47,7 +48,7 @@ QList> EgenioussReceiver::details() return detailsList; } - detailsList.append( qMakePair( "q", mPayload.value( "q" ).toString() ) ); + detailsList.append( qMakePair( "q", mPayload.value( "q" ).toDouble() ) ); return detailsList; } diff --git a/src/core/positioning/egenioussreceiver.h b/src/core/positioning/egenioussreceiver.h index 724e48a4cd..2ba617eddc 100644 --- a/src/core/positioning/egenioussreceiver.h +++ b/src/core/positioning/egenioussreceiver.h @@ -1,4 +1,5 @@ -#pragma once +#ifndef EGENIOUSSRECEIVER_H +#define EGENIOUSSRECEIVER_H #include "abstractgnssreceiver.h" @@ -32,3 +33,5 @@ class EgenioussReceiver : public AbstractGnssReceiver const QHostAddress::SpecialAddress mAddress = QHostAddress::LocalHost; const int mPort = 1235; }; + +#endif // EGENIOUSSRECEIVER_H From cd74cc9b038993112fa4bbb490caba6b3bdc1ca2 Mon Sep 17 00:00:00 2001 From: Mohsen Date: Sat, 14 Sep 2024 22:15:19 +0330 Subject: [PATCH 13/24] [Try 1] to fix startup crash. Reproduce crash: 1- open app. 2- grant permissions. 3- app crashed. 4- reopen the app -- OK! --- src/core/positioning/egenioussreceiver.cpp | 8 +++++++- src/core/positioning/positioningdevicemodel.cpp | 2 +- src/qml/QFieldSettings.qml | 4 ++++ 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/core/positioning/egenioussreceiver.cpp b/src/core/positioning/egenioussreceiver.cpp index 5d002953d6..862f4f692b 100644 --- a/src/core/positioning/egenioussreceiver.cpp +++ b/src/core/positioning/egenioussreceiver.cpp @@ -5,7 +5,7 @@ #include EgenioussReceiver::EgenioussReceiver( QObject *parent ) - : AbstractGnssReceiver( parent ), mTcpSocket( new QTcpSocket( this ) ) + : AbstractGnssReceiver( parent ), mTcpSocket( new QTcpSocket() ) { connect( mTcpSocket, &QTcpSocket::readyRead, this, &EgenioussReceiver::onReadyRead ); connect( mTcpSocket, &QTcpSocket::errorOccurred, this, &EgenioussReceiver::onErrorOccurred ); @@ -13,6 +13,12 @@ EgenioussReceiver::EgenioussReceiver( QObject *parent ) connect( mTcpSocket, &QTcpSocket::disconnected, this, &EgenioussReceiver::disconnected ); } +EgenioussReceiver::~EgenioussReceiver() +{ + mTcpSocket->deleteLater(); + mTcpSocket = nullptr; +} + void EgenioussReceiver::handleConnectDevice() { mTcpSocket->connectToHost( mAddress, mPort, QTcpSocket::ReadWrite ); diff --git a/src/core/positioning/positioningdevicemodel.cpp b/src/core/positioning/positioningdevicemodel.cpp index 17eb82a612..553f5e22b6 100644 --- a/src/core/positioning/positioningdevicemodel.cpp +++ b/src/core/positioning/positioningdevicemodel.cpp @@ -173,7 +173,7 @@ const QString PositioningDeviceModel::deviceId( const Device &device ) const return QStringLiteral( "serial:%1" ).arg( device.settings.value( QStringLiteral( "address" ) ).toString() ); case EgenioussDevice: - return QStringLiteral( "egeniouss:%1:%2" ).arg( device.settings.value( QStringLiteral( "address" ) ).toString(), QString::number( device.settings.value( QStringLiteral( "port" ) ).toInt() ) ); + return QStringLiteral( "egeniouss:" ); } return QString(); diff --git a/src/qml/QFieldSettings.qml b/src/qml/QFieldSettings.qml index 35c191704f..09f3c37505 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_serial_port_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_serial_port_receiver_black_24dp'); } return ''; } From deca732144a31de97c78c77209f702c58e6b36b0 Mon Sep 17 00:00:00 2001 From: Mohsen Date: Sun, 15 Sep 2024 16:33:10 +0330 Subject: [PATCH 14/24] [Try 2] Remove destructor. --- src/core/positioning/egenioussreceiver.cpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/core/positioning/egenioussreceiver.cpp b/src/core/positioning/egenioussreceiver.cpp index 862f4f692b..d47ae28695 100644 --- a/src/core/positioning/egenioussreceiver.cpp +++ b/src/core/positioning/egenioussreceiver.cpp @@ -13,12 +13,6 @@ EgenioussReceiver::EgenioussReceiver( QObject *parent ) connect( mTcpSocket, &QTcpSocket::disconnected, this, &EgenioussReceiver::disconnected ); } -EgenioussReceiver::~EgenioussReceiver() -{ - mTcpSocket->deleteLater(); - mTcpSocket = nullptr; -} - void EgenioussReceiver::handleConnectDevice() { mTcpSocket->connectToHost( mAddress, mPort, QTcpSocket::ReadWrite ); From 65c6d8b0a6b05e5ff61d5cdf8db644356927aea4 Mon Sep 17 00:00:00 2001 From: Mohsen Date: Sun, 15 Sep 2024 17:02:58 +0330 Subject: [PATCH 15/24] [Try 3] add "this" to requestPermission. When we launch the app, it requests the internal receiver permission but then immediately change that to external, killing the object that called the permission. --- src/core/positioning/internalgnssreceiver.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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; From 733034755317964a9e7ea7ee3b2ea40fc1b0842f Mon Sep 17 00:00:00 2001 From: Mohsen Date: Sun, 15 Sep 2024 18:28:37 +0330 Subject: [PATCH 16/24] Cleanup ui and some clean code. --- src/core/positioning/egenioussreceiver.cpp | 22 ++++++-- src/core/positioning/egenioussreceiver.h | 2 +- .../positioning/positioninginformationmodel.h | 5 +- src/core/positioning/tcpreceiver.cpp | 2 +- src/qml/EgenioussDeviceChooser.qml | 50 ++----------------- 5 files changed, 28 insertions(+), 53 deletions(-) diff --git a/src/core/positioning/egenioussreceiver.cpp b/src/core/positioning/egenioussreceiver.cpp index d47ae28695..caefc6259f 100644 --- a/src/core/positioning/egenioussreceiver.cpp +++ b/src/core/positioning/egenioussreceiver.cpp @@ -8,7 +8,7 @@ EgenioussReceiver::EgenioussReceiver( QObject *parent ) : AbstractGnssReceiver( parent ), mTcpSocket( new QTcpSocket() ) { connect( mTcpSocket, &QTcpSocket::readyRead, this, &EgenioussReceiver::onReadyRead ); - connect( mTcpSocket, &QTcpSocket::errorOccurred, this, &EgenioussReceiver::onErrorOccurred ); + connect( mTcpSocket, &QTcpSocket::errorOccurred, this, &EgenioussReceiver::handleError ); connect( mTcpSocket, &QTcpSocket::connected, this, &EgenioussReceiver::connected ); connect( mTcpSocket, &QTcpSocket::disconnected, this, &EgenioussReceiver::disconnected ); } @@ -101,8 +101,24 @@ void EgenioussReceiver::onReadyRead() emit lastGnssPositionInformationChanged( mLastGnssPositionInformation ); } -void EgenioussReceiver::onErrorOccurred( QAbstractSocket::SocketError socketError ) +void EgenioussReceiver::handleError( QAbstractSocket::SocketError error ) { - mLastError = mTcpSocket->errorString(); + 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; + } + qInfo() << QStringLiteral( "EgenioussReceiver: Error: %1" ).arg( mLastError ); + emit lastErrorChanged( mLastError ); } diff --git a/src/core/positioning/egenioussreceiver.h b/src/core/positioning/egenioussreceiver.h index 2ba617eddc..6f2e5d835d 100644 --- a/src/core/positioning/egenioussreceiver.h +++ b/src/core/positioning/egenioussreceiver.h @@ -20,7 +20,7 @@ class EgenioussReceiver : public AbstractGnssReceiver private slots: void onReadyRead(); - void onErrorOccurred( QAbstractSocket::SocketError socketError ); + void handleError( QAbstractSocket::SocketError socketError ); private: void processReceivedData(); 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 index 1f02442abb..74b2980a0f 100644 --- a/src/qml/EgenioussDeviceChooser.qml +++ b/src/qml/EgenioussDeviceChooser.qml @@ -7,59 +7,15 @@ import Theme Item { width: parent.width - property alias deviceAddress: egenioussDeviceAddress.text - property alias devicePort: egenioussDevicePort.text - function generateName() { - return deviceAddress + ' (' + devicePort + ')'; + return "Egeniouss"; } function setSettings(settings) { - deviceAddress = settings['address']; - devicePort = settings['port']; + // nothing to save! } function getSettings() { - return { - "address": deviceAddress.trim(), - "port": parseInt(devicePort) - }; - } - - GridLayout { - width: parent.width - columns: 1 - columnSpacing: 0 - rowSpacing: 5 - - Label { - Layout.fillWidth: true - text: qsTr("Address:") - font: Theme.defaultFont - wrapMode: Text.WordWrap - } - - QfTextField { - id: egenioussDeviceAddress - Layout.fillWidth: true - font: Theme.defaultFont - text: '127.0.0.1' - inputMethodHints: Qt.ImhNoPredictiveText | Qt.ImhNoAutoUppercase | Qt.ImhPreferLowercase - } - - Label { - Layout.fillWidth: true - text: qsTr("Port:") - font: Theme.defaultFont - wrapMode: Text.WordWrap - } - - QfTextField { - id: egenioussDevicePort - Layout.fillWidth: true - font: Theme.defaultFont - text: '1235' - inputMethodHints: Qt.ImhFormattedNumbersOnly - } + return {}; } } From d30d81f9152c75d311e3b9f3dc1e871516e1f929 Mon Sep 17 00:00:00 2001 From: Mohsen Date: Sun, 15 Sep 2024 19:03:17 +0330 Subject: [PATCH 17/24] Add egeniouss icon. --- images/images.qrc | 1 + .../themes/qfield/nodpi/ic_egeniouss_receiver_black_24dp.svg | 1 + src/qml/PositioningDeviceSettings.qml | 4 ++-- src/qml/QFieldSettings.qml | 4 ++-- 4 files changed, 6 insertions(+), 4 deletions(-) create mode 100644 images/themes/qfield/nodpi/ic_egeniouss_receiver_black_24dp.svg 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/qml/PositioningDeviceSettings.qml b/src/qml/PositioningDeviceSettings.qml index b10685c391..d69b78f35c 100644 --- a/src/qml/PositioningDeviceSettings.qml +++ b/src/qml/PositioningDeviceSettings.qml @@ -131,7 +131,7 @@ Popup { case PositioningDeviceModel.SerialPortDevice: return Theme.getThemeVectorIcon('ic_serial_port_receiver_black_24dp'); case PositioningDeviceModel.EgenioussDevice: - return Theme.getThemeVectorIcon('ic_serial_port_receiver_black_24dp'); + return Theme.getThemeVectorIcon('ic_egeniouss_receiver_black_24dp'); } return ''; } @@ -157,7 +157,7 @@ Popup { case PositioningDeviceModel.SerialPortDevice: return Theme.getThemeVectorIcon('ic_serial_port_receiver_black_24dp'); case PositioningDeviceModel.EgenioussDevice: - return Theme.getThemeVectorIcon('ic_serial_port_receiver_black_24dp'); + return Theme.getThemeVectorIcon('ic_egeniouss_receiver_black_24dp'); } return ''; } diff --git a/src/qml/QFieldSettings.qml b/src/qml/QFieldSettings.qml index 09f3c37505..180a914336 100644 --- a/src/qml/QFieldSettings.qml +++ b/src/qml/QFieldSettings.qml @@ -872,7 +872,7 @@ Page { case PositioningDeviceModel.SerialPortDevice: return Theme.getThemeVectorIcon('ic_serial_port_receiver_black_24dp'); case PositioningDeviceModel.EgenioussDevice: - return Theme.getThemeVectorIcon('ic_serial_port_receiver_black_24dp'); + return Theme.getThemeVectorIcon('ic_egeniouss_receiver_black_24dp'); } return ''; } @@ -900,7 +900,7 @@ Page { case PositioningDeviceModel.SerialPortDevice: return Theme.getThemeVectorIcon('ic_serial_port_receiver_black_24dp'); case PositioningDeviceModel.EgenioussDevice: - return Theme.getThemeVectorIcon('ic_serial_port_receiver_black_24dp'); + return Theme.getThemeVectorIcon('ic_egeniouss_receiver_black_24dp'); } return ''; } From 5c72442dd4a2c59f5a86f81a0ab60e4eb3f778f7 Mon Sep 17 00:00:00 2001 From: Mohsen Date: Sun, 15 Sep 2024 19:07:24 +0330 Subject: [PATCH 18/24] Fix style. --- src/core/positioning/egenioussreceiver.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/positioning/egenioussreceiver.h b/src/core/positioning/egenioussreceiver.h index 6f2e5d835d..d4de3c10a7 100644 --- a/src/core/positioning/egenioussreceiver.h +++ b/src/core/positioning/egenioussreceiver.h @@ -20,7 +20,7 @@ class EgenioussReceiver : public AbstractGnssReceiver private slots: void onReadyRead(); - void handleError( QAbstractSocket::SocketError socketError ); + void handleError( QAbstractSocket::SocketError error ); private: void processReceivedData(); From ea00df0674d88be569fa45dc1dda30839e04271f Mon Sep 17 00:00:00 2001 From: Mohsen Date: Mon, 16 Sep 2024 23:15:12 +0330 Subject: [PATCH 19/24] Enable egeniouss receiver using plugin. --- src/qml/PluginManagerSettings.qml | 5 +++++ src/qml/PositioningDeviceSettings.qml | 25 +++++++++++++++++++++---- src/qml/PositioningSettings.qml | 1 + src/qml/qgismobileapp.qml | 7 +++++++ 4 files changed, 34 insertions(+), 4 deletions(-) diff --git a/src/qml/PluginManagerSettings.qml b/src/qml/PluginManagerSettings.qml index 44c83b1bd9..0c00942215 100644 --- a/src/qml/PluginManagerSettings.qml +++ b/src/qml/PluginManagerSettings.qml @@ -14,6 +14,9 @@ Popup { y: (parent.height - height) / 2 padding: 0 + signal unLoadClicked(string Uuid) + signal loadClicked(string Uuid) + Page { id: page width: parent.width @@ -119,8 +122,10 @@ Popup { Enabled = checked == true; if (Enabled) { pluginManager.enableAppPlugin(Uuid); + loadClicked(Uuid); } else { pluginManager.disableAppPlugin(Uuid); + unLoadClicked(Uuid); } } } diff --git a/src/qml/PositioningDeviceSettings.qml b/src/qml/PositioningDeviceSettings.qml index d69b78f35c..7969f1bf1d 100644 --- a/src/qml/PositioningDeviceSettings.qml +++ b/src/qml/PositioningDeviceSettings.qml @@ -41,6 +41,20 @@ Popup { return positioningDeviceItem.item.getSettings(); } + function handleEgenioussChange() { + if (positioningSettings.enableEgeniouss) { + 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.enableEgeniouss) { + positioningDeviceTypeModel.insert(0, { + "name": qsTr('Egeniouss'), + "value": PositioningDeviceModel.EgenioussDevice + }); + } positioningDeviceType.model = positioningDeviceTypeModel; + positioningSettings.onEnableEgenioussChanged.connect(handleEgenioussChange); } Page { @@ -181,10 +202,6 @@ Popup { name: qsTr('UDP (NMEA)') value: PositioningDeviceModel.UdpDevice } - ListElement { - name: qsTr('Egeniouss') - value: PositioningDeviceModel.EgenioussDevice - } } Loader { diff --git a/src/qml/PositioningSettings.qml b/src/qml/PositioningSettings.qml index 87c0a5b4e2..ba14c1b3f9 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 enableEgeniouss: false } diff --git a/src/qml/qgismobileapp.qml b/src/qml/qgismobileapp.qml index 7626ec4903..0e343062eb 100644 --- a/src/qml/qgismobileapp.qml +++ b/src/qml/qgismobileapp.qml @@ -243,6 +243,7 @@ ApplicationWindow { PositioningSettings { id: positioningSettings + objectName: "positioningSettings" onPositioningActivatedChanged: { if (positioningActivated) { @@ -2076,6 +2077,12 @@ ApplicationWindow { modal: true closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside parent: Overlay.overlay + + onUnLoadClicked: function (Uuid) { + if (Uuid.search === "qfield-egeniouss-plugin") { + positioningSettings.enableEgeniouss = false; + } + } } DashBoard { From 781d9f9e6fde35bb7ecd4e659e12784b1987eca9 Mon Sep 17 00:00:00 2001 From: Mohsen Date: Wed, 18 Sep 2024 16:52:42 +0330 Subject: [PATCH 20/24] Plugin manager signal when enabling / disabling plugin. Use plugin manager to call function attached to the plugin Item {} itself when enabling / disabling a plugin. --- src/core/pluginmanager.cpp | 26 ++++++++++++++++++++++++++ src/core/pluginmanager.h | 2 ++ src/qml/PluginManagerSettings.qml | 5 ----- src/qml/qgismobileapp.qml | 6 ------ 4 files changed, 28 insertions(+), 11 deletions(-) diff --git a/src/core/pluginmanager.cpp b/src/core/pluginmanager.cpp index 9c2c48cd09..9b7adc8d8b 100644 --- a/src/core/pluginmanager.cpp +++ b/src/core/pluginmanager.cpp @@ -288,10 +288,12 @@ void PluginManager::enableAppPlugin( const QString &uuid ) loadPlugin( mAvailableAppPlugins[uuid].path(), mAvailableAppPlugins[uuid].name() ); } } + callPluginMethod( uuid, "appWideActivated" ); } void PluginManager::disableAppPlugin( const QString &uuid ) { + callPluginMethod( uuid, "appWideDisabled" ); if ( mAvailableAppPlugins.contains( uuid ) ) { if ( mLoadedPlugins.contains( mAvailableAppPlugins[uuid].path() ) ) @@ -455,3 +457,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 methodExists = object->metaObject()->indexOfSlot( normalizedSignature ); + + if ( methodExists != -1 ) + { + QMetaObject::invokeMethod( object.data(), methodName.toStdString().c_str() ); + } +} diff --git a/src/core/pluginmanager.h b/src/core/pluginmanager.h index 7be7e30b0d..a8027e308b 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 &slotName ); private: QQmlEngine *mEngine = nullptr; diff --git a/src/qml/PluginManagerSettings.qml b/src/qml/PluginManagerSettings.qml index 0c00942215..44c83b1bd9 100644 --- a/src/qml/PluginManagerSettings.qml +++ b/src/qml/PluginManagerSettings.qml @@ -14,9 +14,6 @@ Popup { y: (parent.height - height) / 2 padding: 0 - signal unLoadClicked(string Uuid) - signal loadClicked(string Uuid) - Page { id: page width: parent.width @@ -122,10 +119,8 @@ Popup { Enabled = checked == true; if (Enabled) { pluginManager.enableAppPlugin(Uuid); - loadClicked(Uuid); } else { pluginManager.disableAppPlugin(Uuid); - unLoadClicked(Uuid); } } } diff --git a/src/qml/qgismobileapp.qml b/src/qml/qgismobileapp.qml index 0e343062eb..2cece6ee17 100644 --- a/src/qml/qgismobileapp.qml +++ b/src/qml/qgismobileapp.qml @@ -2077,12 +2077,6 @@ ApplicationWindow { modal: true closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside parent: Overlay.overlay - - onUnLoadClicked: function (Uuid) { - if (Uuid.search === "qfield-egeniouss-plugin") { - positioningSettings.enableEgeniouss = false; - } - } } DashBoard { From 183fd285e93e9ebb0028a13f96ff3f6728ae12e9 Mon Sep 17 00:00:00 2001 From: Mohsen Date: Mon, 23 Sep 2024 17:07:56 +0330 Subject: [PATCH 21/24] Address issues. Changes list: - Rename to `appWideEnabled` - Rename to `egenioussEnabled` - Set `mSocketStateString` and `mSocketState` - Use `const` variables in `onReadyRead` --- src/core/pluginmanager.cpp | 6 ++-- src/core/positioning/egenioussreceiver.cpp | 32 ++++++++++++++++------ src/qml/PositioningDeviceSettings.qml | 6 ++-- src/qml/PositioningSettings.qml | 2 +- 4 files changed, 31 insertions(+), 15 deletions(-) diff --git a/src/core/pluginmanager.cpp b/src/core/pluginmanager.cpp index 9b7adc8d8b..4bf8002ef4 100644 --- a/src/core/pluginmanager.cpp +++ b/src/core/pluginmanager.cpp @@ -288,7 +288,7 @@ void PluginManager::enableAppPlugin( const QString &uuid ) loadPlugin( mAvailableAppPlugins[uuid].path(), mAvailableAppPlugins[uuid].name() ); } } - callPluginMethod( uuid, "appWideActivated" ); + callPluginMethod( uuid, "appWideEnabled" ); } void PluginManager::disableAppPlugin( const QString &uuid ) @@ -474,9 +474,9 @@ void PluginManager::callPluginMethod( const QString &uuid, const QString &method const QPointer object = mLoadedPlugins[pluginPath]; const char *normalizedSignature = QMetaObject::normalizedSignature( ( methodName + "()" ).toStdString().c_str() ); - const int methodExists = object->metaObject()->indexOfSlot( normalizedSignature ); + const int methodIndex = object->metaObject()->indexOfSlot( normalizedSignature ); - if ( methodExists != -1 ) + if ( methodIndex != -1 ) { QMetaObject::invokeMethod( object.data(), methodName.toStdString().c_str() ); } diff --git a/src/core/positioning/egenioussreceiver.cpp b/src/core/positioning/egenioussreceiver.cpp index caefc6259f..0de5e2efaa 100644 --- a/src/core/positioning/egenioussreceiver.cpp +++ b/src/core/positioning/egenioussreceiver.cpp @@ -21,6 +21,7 @@ void EgenioussReceiver::handleConnectDevice() void EgenioussReceiver::connected() { mSocketState = QAbstractSocket::ConnectedState; + mSocketStateString = tr( "Successfully connected" ); emit socketStateChanged( mSocketState ); setValid( true ); } @@ -35,6 +36,7 @@ void EgenioussReceiver::disconnected() if ( mTcpSocket->state() == QAbstractSocket::ConnectedState ) { mSocketState = QAbstractSocket::UnconnectedState; + mSocketStateString = tr( "Disconnected" ); emit socketStateChanged( mSocketState ); } } @@ -55,27 +57,39 @@ QList> EgenioussReceiver::details() void EgenioussReceiver::onReadyRead() { + const int minimumDataSize = 9; + const uint8_t validStartByte = 0xFE; + const int payloadHeaderSize = 8; + QByteArray mReceivedData = mTcpSocket->readAll(); - if ( mReceivedData.size() < 9 ) + if ( mReceivedData.size() < minimumDataSize ) { - return; // Received data is too short to process. + mLastError = tr( "Received data is too short to process" ); + emit lastErrorChanged( mLastError ); + return; } - if ( static_cast( mReceivedData[0] ) != 0xFE ) + if ( static_cast( mReceivedData[0] ) != validStartByte ) { - return; // Invalid start byte + 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() < 8 + payloadLength ) + if ( mReceivedData.size() < payloadHeaderSize + payloadLength ) { - return; // Received data is too short to contain the payload. + mLastError = tr( "Received data is too short to contain the payload" ); + emit lastErrorChanged( mLastError ); + return; } - QJsonDocument jsonDoc = QJsonDocument::fromJson( mReceivedData.mid( 8, payloadLength ) ); + QJsonDocument jsonDoc = QJsonDocument::fromJson( mReceivedData.mid( payloadHeaderSize, payloadLength ) ); if ( jsonDoc.isNull() || !jsonDoc.isObject() ) { - return; // Failed to parse JSON + 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(); @@ -118,6 +132,8 @@ void EgenioussReceiver::handleError( QAbstractSocket::SocketError error ) 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/qml/PositioningDeviceSettings.qml b/src/qml/PositioningDeviceSettings.qml index 7969f1bf1d..d6915faa7b 100644 --- a/src/qml/PositioningDeviceSettings.qml +++ b/src/qml/PositioningDeviceSettings.qml @@ -42,7 +42,7 @@ Popup { } function handleEgenioussChange() { - if (positioningSettings.enableEgeniouss) { + if (positioningSettings.egenioussEnabled) { positioningDeviceTypeModel.insert(0, { "name": qsTr('Egeniouss'), "value": PositioningDeviceModel.EgenioussDevice @@ -68,14 +68,14 @@ Popup { "value": PositioningDeviceModel.SerialPortDevice }); } - if (positioningSettings.enableEgeniouss) { + if (positioningSettings.egenioussEnabled) { positioningDeviceTypeModel.insert(0, { "name": qsTr('Egeniouss'), "value": PositioningDeviceModel.EgenioussDevice }); } positioningDeviceType.model = positioningDeviceTypeModel; - positioningSettings.onEnableEgenioussChanged.connect(handleEgenioussChange); + positioningSettings.onEgenioussEnabledChanged.connect(handleEgenioussChange); } Page { diff --git a/src/qml/PositioningSettings.qml b/src/qml/PositioningSettings.qml index ba14c1b3f9..614c988edd 100644 --- a/src/qml/PositioningSettings.qml +++ b/src/qml/PositioningSettings.qml @@ -45,5 +45,5 @@ Settings { property int digitizingMeasureType: 1 property bool geofencingPreventDigitizingDuringAlert: false - property bool enableEgeniouss: false + property bool egenioussEnabled: false } From 12f5ae57ce865d46e0bc0c9e1b1239b95cb03022 Mon Sep 17 00:00:00 2001 From: Mohsen Date: Mon, 23 Sep 2024 19:45:11 +0330 Subject: [PATCH 22/24] Fix permission problem in android. --- src/core/pluginmanager.cpp | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/src/core/pluginmanager.cpp b/src/core/pluginmanager.cpp index 4bf8002ef4..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,10 +292,14 @@ 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" ); + } } } - callPluginMethod( uuid, "appWideEnabled" ); } void PluginManager::disableAppPlugin( const QString &uuid ) From d05d01317e34ae1cf2593d649ea785203cc91fe5 Mon Sep 17 00:00:00 2001 From: Mohsen Date: Mon, 23 Sep 2024 20:32:33 +0330 Subject: [PATCH 23/24] Fix losing the positioning button on the lower right corner. setValid( true ) on constructor --- src/core/positioning/egenioussreceiver.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/core/positioning/egenioussreceiver.cpp b/src/core/positioning/egenioussreceiver.cpp index 0de5e2efaa..70266bb154 100644 --- a/src/core/positioning/egenioussreceiver.cpp +++ b/src/core/positioning/egenioussreceiver.cpp @@ -11,6 +11,7 @@ EgenioussReceiver::EgenioussReceiver( QObject *parent ) 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() From 70205944233f45f7f57b8b3c7326e084b681837c Mon Sep 17 00:00:00 2001 From: Mohsen Date: Tue, 24 Sep 2024 17:04:32 +0330 Subject: [PATCH 24/24] Fix style. --- src/core/pluginmanager.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/pluginmanager.h b/src/core/pluginmanager.h index a8027e308b..2d6375ecfe 100644 --- a/src/core/pluginmanager.h +++ b/src/core/pluginmanager.h @@ -115,7 +115,7 @@ class PluginManager : public QObject private slots: void handleWarnings( const QList &warnings ); - void callPluginMethod( const QString &uuid, const QString &slotName ); + void callPluginMethod( const QString &uuid, const QString &methodName ); private: QQmlEngine *mEngine = nullptr;