Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Merge pull request #52329 from nirvn/sensors_framework_2
Sensor options panel within the project properties dialog
  • Loading branch information
nirvn committed Mar 28, 2023
2 parents cb7416a + 00b53e7 commit 346abae
Show file tree
Hide file tree
Showing 23 changed files with 1,047 additions and 1 deletion.
1 change: 1 addition & 0 deletions images/images.qrc
Expand Up @@ -639,6 +639,7 @@
<file>themes/default/propertyicons/colors.svg</file>
<file>themes/default/propertyicons/system.svg</file>
<file>themes/default/propertyicons/transparency.svg</file>
<file>themes/default/propertyicons/sensor.svg</file>
<file>themes/default/propertyicons/spacer.svg</file>
<file>themes/default/propertyicons/relations.svg</file>
<file>themes/default/rendererCategorizedSymbol.svg</file>
Expand Down
6 changes: 5 additions & 1 deletion images/themes/default/mActionStop.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 11 additions & 0 deletions images/themes/default/propertyicons/sensor.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
73 changes: 73 additions & 0 deletions python/core/auto_generated/sensor/qgssensormodel.sip.in
@@ -0,0 +1,73 @@
/************************************************************************
* This file has been generated automatically from *
* *
* src/core/sensor/qgssensormodel.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/





class QgsSensorModel: QAbstractItemModel
{
%Docstring(signature="appended")
A QAbstractItemModel subclass for showing sensors within a :py:class:`QgsSensorManager`.

.. versionadded:: 3.32
%End

%TypeHeaderCode
#include "qgssensormodel.h"
%End
public:

enum class Column
{
Name,
LastValue,
};

enum Role
{
SensorType,
SensorId,
SensorName,
SensorStatus,
SensorLastValue,
SensorLastTimestamp,
Sensor,
};

explicit QgsSensorModel( QgsSensorManager *manager, QObject *parent /TransferThis/ = 0 );
%Docstring
Constructor for QgsSensorModel, for the specified ``manager`` and ``parent`` object.
%End

virtual QVariant data( const QModelIndex &index, int role ) const;

virtual bool setData( const QModelIndex &index, const QVariant &value, int role = Qt::EditRole );

virtual Qt::ItemFlags flags( const QModelIndex &index ) const;

virtual QVariant headerData( int section, Qt::Orientation orientation,
int role = Qt::DisplayRole ) const;
virtual QModelIndex index( int row, int column,
const QModelIndex &parent = QModelIndex() ) const;
virtual QModelIndex parent( const QModelIndex &index ) const;

virtual int rowCount( const QModelIndex &parent = QModelIndex() ) const;

virtual int columnCount( const QModelIndex &parent = QModelIndex() ) const;


};

/************************************************************************
* This file has been generated automatically from *
* *
* src/core/sensor/qgssensormodel.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/
1 change: 1 addition & 0 deletions python/core/core_auto.sip
Expand Up @@ -703,6 +703,7 @@
%Include auto_generated/textrenderer/qgstextrenderer.sip
%Include auto_generated/textrenderer/qgstextrendererutils.sip
%Include auto_generated/textrenderer/qgstextshadowsettings.sip
%Include auto_generated/sensor/qgssensormodel.sip
%Include auto_generated/sensor/qgssensormanager.sip
%Include auto_generated/sensor/qgssensorregistry.sip
%Include auto_generated/sensor/qgsabstractsensor.sip
Expand Down
6 changes: 6 additions & 0 deletions python/gui/auto_generated/qgsoptionswidgetfactory.sip.in
Expand Up @@ -56,6 +56,12 @@ The default implementation returns ``True``.
%Docstring
Called to permanently apply the settings shown in the options page (e.g. save them to
:py:class:`QgsSettings` objects). This is usually called when the options dialog is accepted.
%End

virtual void cancel();
%Docstring
Called to cancel settings changed in the options page (e.g. save them to
:py:class:`QgsSettings` objects). This is usually called when the options dialog is canceled.
%End

protected:
Expand Down
4 changes: 4 additions & 0 deletions src/app/CMakeLists.txt
Expand Up @@ -272,6 +272,9 @@ set(QGIS_APP_SRCS
gps/qgsgpsmarker.cpp
gps/qgsgpstoolbar.cpp

sensor/qgssensortablewidget.cpp
sensor/qgsprojectsensorsettingswidget.cpp

project/qgsprojectelevationsettingswidget.cpp

pluginmanager/qgspluginmanager.cpp
Expand Down Expand Up @@ -525,6 +528,7 @@ target_include_directories(qgis_app PUBLIC
${CMAKE_SOURCE_DIR}/src/app/layout
${CMAKE_SOURCE_DIR}/src/app/pluginmanager
${CMAKE_SOURCE_DIR}/src/app/gps
${CMAKE_SOURCE_DIR}/src/app/sensor
${CMAKE_SOURCE_DIR}/src/app/dwg
${CMAKE_SOURCE_DIR}/src/app/maptools
${CMAKE_SOURCE_DIR}/src/app/mesh
Expand Down
3 changes: 3 additions & 0 deletions src/app/qgisapp.cpp
Expand Up @@ -443,7 +443,9 @@ Q_GUI_EXPORT extern int qt_defaultDpiX();
#include "pointcloud/qgspointcloudlayerstylewidget.h"
#include "pointcloud/qgspointcloudlayersaveasdialog.h"
#include "pointcloud/qgspointcloudlayerexporter.h"

#include "project/qgsprojectelevationsettingswidget.h"
#include "sensor/qgsprojectsensorsettingswidget.h"

#include "qgsmaptoolsdigitizingtechniquemanager.h"
#include "qgsmaptoolshaperegistry.h"
Expand Down Expand Up @@ -1508,6 +1510,7 @@ QgisApp::QgisApp( QSplashScreen *splash, bool restorePlugins, bool skipBadLayers

registerMapLayerPropertiesFactory( new QgsElevationShadingRendererSettingsWidgetFactory( this ) );
registerProjectPropertiesWidgetFactory( new QgsProjectElevationSettingsWidgetFactory( this ) );
registerProjectPropertiesWidgetFactory( new QgsProjectSensorSettingsWidgetFactory( this ) );

activateDeactivateLayerRelatedActions( nullptr ); // after members were created

Expand Down
9 changes: 9 additions & 0 deletions src/app/qgsprojectproperties.cpp
Expand Up @@ -182,6 +182,7 @@ QgsProjectProperties::QgsProjectProperties( QgsMapCanvas *mapCanvas, QWidget *pa
projectionSelector->setShowNoProjection( true );

connect( buttonBox->button( QDialogButtonBox::Apply ), &QAbstractButton::clicked, this, &QgsProjectProperties::apply );
connect( this, &QDialog::finished, this, [ = ]( int result ) { if ( result == QDialog::Rejected ) cancel(); } );

// disconnect default connection setup by initOptionsBase for accepting dialog, and insert logic
// to validate widgets before allowing dialog to be closed
Expand Down Expand Up @@ -1738,6 +1739,14 @@ void QgsProjectProperties::apply()
}
}

void QgsProjectProperties::cancel()
{
for ( QgsOptionsPageWidget *widget : std::as_const( mAdditionalProjectPropertiesWidgets ) )
{
widget->cancel();
}
}

void QgsProjectProperties::lwWmsRowsInserted( const QModelIndex &parent, int first, int last )
{
Q_UNUSED( parent )
Expand Down
5 changes: 5 additions & 0 deletions src/app/qgsprojectproperties.h
Expand Up @@ -80,6 +80,11 @@ class APP_EXPORT QgsProjectProperties : public QgsOptionsDialogBase, private Ui:
*/
void apply();

/**
* Slot called when cancel button is pressed or dialog is not accepted
*/
void cancel();

/**
* Let the user add a scale to the list of project scales
* used in scale combobox instead of global ones.
Expand Down
93 changes: 93 additions & 0 deletions src/app/sensor/qgsprojectsensorsettingswidget.cpp
@@ -0,0 +1,93 @@
/***************************************************************************
qgsprojectsensorsettingswidget.cpp
---------------------
begin : March 2022
copyright : (C) 2022 by Nyall Dawson
email : nyall dot dawson at gmail dot com
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

#include "qgsprojectsensorsettingswidget.h"

#include "qgis.h"
#include "qgsabstractsensor.h"
#include "qgsapplication.h"
#include "qgsproject.h"
#include "qgssensormanager.h"

QgsProjectSensorSettingsWidget::QgsProjectSensorSettingsWidget( QWidget *parent )
: QgsOptionsPageWidget( parent )
{
setupUi( this );

QDomElement sensorElem = QgsProject::instance()->sensorManager()->writeXml( mPreviousSensors );
mPreviousSensors.appendChild( sensorElem );

const QList<QgsAbstractSensor *> sensors = QgsProject::instance()->sensorManager()->sensors();
for ( QgsAbstractSensor *sensor : sensors )
{
if ( sensor->status() == Qgis::DeviceConnectionStatus::Connected )
{
mConnectedSensors << sensor->id();
}
}
}

void QgsProjectSensorSettingsWidget::cancel()
{
// Capture connected state of current sensors even if we're about to revert as someone might have
// activated a sensor then closed the dialog using the window bar's close button
QList<QgsAbstractSensor *> sensors = QgsProject::instance()->sensorManager()->sensors();
for ( QgsAbstractSensor *sensor : sensors )
{
if ( sensor->status() == Qgis::DeviceConnectionStatus::Connected )
{
mConnectedSensors << sensor->id();
}
}

QgsProject::instance()->sensorManager()->clear();
QgsProject::instance()->sensorManager()->readXml( mPreviousSensors.documentElement(), mPreviousSensors );

sensors = QgsProject::instance()->sensorManager()->sensors();
for ( QgsAbstractSensor *sensor : sensors )
{
if ( mConnectedSensors.contains( sensor->id() ) )
{
sensor->connectSensor();
}
}
}

void QgsProjectSensorSettingsWidget::apply()
{
return;
}

bool QgsProjectSensorSettingsWidget::isValid()
{
return true;
}


//
// QgsProjectSensorSettingsWidgetFactory
//

QgsProjectSensorSettingsWidgetFactory::QgsProjectSensorSettingsWidgetFactory( QObject *parent )
: QgsOptionsWidgetFactory( tr( "Sensors" ), QgsApplication::getThemeIcon( QStringLiteral( "propertyicons/sensor.svg" ) ), QStringLiteral( "sensor" ) )
{
setParent( parent );
}


QgsOptionsPageWidget *QgsProjectSensorSettingsWidgetFactory::createWidget( QWidget *parent ) const
{
return new QgsProjectSensorSettingsWidget( parent );
}
55 changes: 55 additions & 0 deletions src/app/sensor/qgsprojectsensorsettingswidget.h
@@ -0,0 +1,55 @@
/***************************************************************************
qgsprojectsensorsettingswidget.h
---------------------
begin : March 2023
copyright : (C) 2023 by Mathieu Pellerin
email : mathieu at opengis dot ch
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

#ifndef QGSPROJECTSENSORSETTINGSWIDGET_H
#define QGSPROJECTSENSORSETTINGSWIDGET_H

#include "ui_qgsprojectsensorettingswidgetbase.h"
#include "qgsoptionswidgetfactory.h"

#include <QDomDocument>

class QgsProjectSensorSettingsWidget : public QgsOptionsPageWidget, private Ui::QgsProjectSensorSettingsWidgetBase
{
Q_OBJECT
public:

QgsProjectSensorSettingsWidget( QWidget *parent = nullptr );

public slots:

bool isValid() override;
void apply() override;
void cancel() override;

private:

QDomDocument mPreviousSensors;
QStringList mConnectedSensors;
};


class QgsProjectSensorSettingsWidgetFactory : public QgsOptionsWidgetFactory
{
Q_OBJECT
public:
explicit QgsProjectSensorSettingsWidgetFactory( QObject *parent = nullptr );

QgsOptionsPageWidget *createWidget( QWidget *parent = nullptr ) const override;
};



#endif // QGSPROJECTSENSORSETTINGSWIDGET_H

0 comments on commit 346abae

Please sign in to comment.