Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 9 additions & 12 deletions app/position/providers/networkpositionprovider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ NetworkPositionProvider::NetworkPositionProvider( const QString &addr, const QSt

void NetworkPositionProvider::startUpdates()
{
// TODO: QHostAddress doesn't support hostname lookup (QHostInfo does)
// NOTE: QHostAddress doesn't support hostname lookup (QHostInfo does)
mTcpSocket->connectToHost( mTargetAddress, mTargetPort );
mUdpSocket->bind( QHostAddress::LocalHost, mTargetPort );
mUdpReconnectTimer.start( ReconnectDelay::ExtraLongDelay );
Expand Down Expand Up @@ -126,14 +126,16 @@ void NetworkPositionProvider::positionUpdateReceived()
{
mUdpSocket->connectToHost( peerAddress.toString(), peerPort );
}

// restart UDP silence timer
mUdpReconnectTimer.start();
return;
}

// stop the UDP silence timer, we just received data
// kills the timer when the app was minimized, and we were able to reconnect in the meantime
// restart the UDP silence timer, we just received data
if ( socket->socketType() == QAbstractSocket::UdpSocket )
{
mUdpReconnectTimer.stop();
mUdpReconnectTimer.start();
}

const QByteArray rawNmeaData = socket->readAll();
Expand Down Expand Up @@ -170,14 +172,9 @@ void NetworkPositionProvider::socketStateChanged( const QAbstractSocket::SocketS
else if ( state == QAbstractSocket::UnconnectedState )
{
const bool isUdpSocketListening = mUdpSocket->state() == QAbstractSocket::ConnectedState || mUdpSocket->state() == QAbstractSocket::BoundState || mUdpReconnectTimer.isActive();
if ( socket->socketType() == QAbstractSocket::TcpSocket && !isUdpSocketListening && QApplication::applicationState() == Qt::ApplicationActive )
{
setState( tr( "No connection" ), State::NoConnection );
startReconnectTimer();
// let's also invalidate current position since we no longer have connection
emit positionChanged( GeoPosition() );
}
else if ( socket->socketType() == QAbstractSocket::UdpSocket && QApplication::applicationState() == Qt::ApplicationActive )
const bool isTcpSocketAndUdpNotListening = socket->socketType() == QAbstractSocket::TcpSocket && !isUdpSocketListening && QApplication::applicationState() == Qt::ApplicationActive;
const bool isUdpSocket = socket->socketType() == QAbstractSocket::UdpSocket && QApplication::applicationState() == Qt::ApplicationActive;
if ( isTcpSocketAndUdpNotListening || isUdpSocket )
{
setState( tr( "No connection" ), State::NoConnection );
startReconnectTimer();
Expand Down
24 changes: 21 additions & 3 deletions app/position/providers/positionprovidersmodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ PositionProvidersModel::PositionProvidersModel( QObject *parent ) : QAbstractLis
{
if ( !InputUtils::isMobilePlatform() )
{
const PositionProvider simulated( "Simulated provider", "Simulated position around point", "internal", "simulated" );
const PositionProvider simulated( tr( "Simulated provider" ), tr( "Simulated position around point" ), QStringLiteral( "internal" ), QStringLiteral( "simulated" ) );

mProviders.push_front( simulated );
}
Expand All @@ -30,8 +30,8 @@ PositionProvidersModel::PositionProvidersModel( QObject *parent ) : QAbstractLis
PositionProvider internal;
internal.name = tr( "Internal" );
internal.description = tr( "GPS receiver of this device" );
internal.providerType = "internal";
internal.providerId = "devicegps";
internal.providerType = QStringLiteral( "internal" );
internal.providerId = QStringLiteral( "devicegps" );

mProviders.push_front( internal );

Expand Down Expand Up @@ -68,6 +68,7 @@ QHash<int, QByteArray> PositionProvidersModel::roleNames() const
roles.insert( DataRoles::ProviderName, QByteArray( "providerName" ) );
roles.insert( DataRoles::ProviderDescription, QByteArray( "providerDescription" ) );
roles.insert( DataRoles::ProviderType, QByteArray( "providerType" ) );
roles.insert( DataRoles::ProviderGroup, QByteArray( "providerGroup" ) );
roles.insert( DataRoles::ProviderId, QByteArray( "providerId" ) );
return roles;
}
Expand Down Expand Up @@ -103,6 +104,15 @@ QVariant PositionProvidersModel::data( const QModelIndex &index, const int role
case DataRoles::ProviderType:
return provider.providerType;

case DataRoles::ProviderGroup:
{
if ( provider.providerType == QStringLiteral( "internal" ) )
{
return QStringLiteral( "internal" );
}
return QStringLiteral( "external" );
}

default:
return {};
}
Expand Down Expand Up @@ -164,6 +174,14 @@ void PositionProvidersModel::addProvider( const QString &name, const QString &pr
}
}

bool PositionProvidersModel::providerExists( const QString &providerId )
{
return std::any_of( mProviders.begin(), mProviders.end(), [providerId]( const PositionProvider & provider )
{
return provider.providerId == providerId;
} );
}

AppSettings *PositionProvidersModel::appSettings() const
{
return mAppSettings;
Expand Down
4 changes: 3 additions & 1 deletion app/position/providers/positionprovidersmodel.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ class PositionProvidersModel : public QAbstractListModel
ProviderName = Qt::UserRole + 1, // name of bluetooth device or custom name for network device
ProviderDescription, // device address (IP/BT) + device type
ProviderId, // device address (IP/BT)
ProviderType // external_ip (connected) / external_bt (connected) / internal (device) / simulated (device)
ProviderType, // external_ip (connected) / external_bt (connected) / internal (device) / simulated (device)
ProviderGroup // internal / external
};
Q_ENUM( DataRoles )

Expand All @@ -69,6 +70,7 @@ class PositionProvidersModel : public QAbstractListModel

Q_INVOKABLE void removeProvider( const QString &providerId );
Q_INVOKABLE void addProvider( const QString &providerName, const QString &providerId, const QString &providerType );
Q_INVOKABLE bool providerExists( const QString &providerId );

AppSettings *appSettings() const;
void setAppSettings( AppSettings * );
Expand Down
6 changes: 3 additions & 3 deletions app/qml/gps/MMExternalProviderConnectionDrawer.qml
Original file line number Diff line number Diff line change
Expand Up @@ -67,18 +67,18 @@ MMComponents.MMDrawer {
: "" )
message.description: root.providerType === "bluetooth"
? qsTr( "We were not able to connect to the specified device. Please make sure your device is powered on and can be connected to." )
: qsTr( "We were not able to connect to the specified IP address. Please try again later." )
: qsTr( "We were not able to connect to the specified IP address." )
message.linkText: qsTr( "Learn more" )
}
},
State {
name: "waitingToReconnect"
when: root.positionProvider && root.positionProvider.state === PositionProvider.WaitingToReconnect
PropertyChanges {
message.image: root.providerType === "bluetooth" ? __style.externalBluetoothGreenImage : __style.externalNetworkGreenImage
message.image: __style.externalGpsRedImage
message.title: root.providerType === "bluetooth"
? qsTr( "We were not able to connect to the specified device. Please make sure your device is powered on and can be connected to." )
: qsTr( "We were not able to connect to the specified IP address. Please try again later." )
: qsTr( "We were not able to connect to the specified IP address." )
message.description: root.positionProvider.stateMessage + "<br><br>" + qsTr( "You can close this message, we will try to repeatedly connect to your device." )
message.linkText: qsTr( "Learn more" )
}
Expand Down
9 changes: 5 additions & 4 deletions app/qml/gps/MMNetworkProviderDrawer.qml
Original file line number Diff line number Diff line change
Expand Up @@ -110,14 +110,15 @@ MMComponents.MMDrawer {
const deviceAddress = ip + ":" + port

root.confirmed( aliasInput.text.trim(), deviceAddress )
root.close()
ipAddressInput.textField.clear()
portInput.textField.clear()
aliasInput.textField.clear()
}
}
}

function showDuplicateProviderError() {
ipAddressInput.errorMsg = qsTr( "Network position provider with this IP address & port already exists" )
portInput.errorMsg = qsTr( "Network position provider with this IP address & port already exists" )
}

onClosed: {
ipAddressInput.textField.clear()
portInput.textField.clear()
Expand Down
14 changes: 10 additions & 4 deletions app/qml/gps/MMPositionProviderPage.qml
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ MMComponents.MMPage {
if ( listdelegate.providerName ) return listdelegate.providerName
return qsTr( "Unknown device" )
}

secondaryText: {
if ( listdelegate.isActive ) {
if ( listdelegate.providerType === "external_ip" )
Expand Down Expand Up @@ -99,12 +100,12 @@ MMComponents.MMPage {
}

section {
property: "providerType"
property: "providerGroup"
delegate: MMComponents.MMText {
required property string section
width: ListView.view.width

text: section === "internal" ? qsTr( "Internal receivers" ) : qsTr( "External receivers" )
text: qsTr( "%1 receivers" ).arg( section === "internal" ? qsTr( "Internal" ) : qsTr( "External" ) )

font: __style.p6
color: __style.nightColor
Expand Down Expand Up @@ -154,7 +155,12 @@ MMComponents.MMPage {
id: networkProviderDrawer

onConfirmed: function( alias, deviceAddress ) {
root.activateProvider( "external_ip", deviceAddress, alias )
if ( providersModel.providerExists( deviceAddress ) ) {
showDuplicateProviderError()
} else {
close()
root.activateProvider( "external_ip", deviceAddress, alias )
}
}
}

Expand Down Expand Up @@ -268,8 +274,8 @@ MMComponents.MMPage {
return // do not construct the same provider again
}

providersModel.addProvider( name, id, type )
PositionKit.positionProvider = PositionKit.constructProvider( type, id, name )
providersModel.addProvider( PositionKit.positionProvider.name(), id, type )

if ( type === "external_bt" ) {
connectingDialogLoader.open( "bluetooth" )
Expand Down
Loading