diff --git a/src/core/providers/sensorthings/qgssensorthingsprovider.h b/src/core/providers/sensorthings/qgssensorthingsprovider.h index ce4e4201c9d..7b0089f648b 100644 --- a/src/core/providers/sensorthings/qgssensorthingsprovider.h +++ b/src/core/providers/sensorthings/qgssensorthingsprovider.h @@ -30,7 +30,7 @@ * * \since QGIS 3.36 */ -class QgsSensorThingsProvider final : public QgsVectorDataProvider +class CORE_EXPORT QgsSensorThingsProvider final : public QgsVectorDataProvider { Q_OBJECT diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt index 694a9702916..f4369f3e76e 100644 --- a/src/gui/CMakeLists.txt +++ b/src/gui/CMakeLists.txt @@ -464,6 +464,7 @@ set(QGIS_GUI_SRCS providers/sensorthings/qgssensorthingsguiprovider.cpp providers/sensorthings/qgssensorthingssourceselect.cpp providers/sensorthings/qgssensorthingssourcewidget.cpp + providers/sensorthings/qgssensorthingssubseteditor.cpp providers/vtpkvectortiles/qgsvtpkvectortileguiprovider.cpp providers/vtpkvectortiles/qgsvtpkvectortilesourcewidget.cpp @@ -1426,6 +1427,7 @@ set(QGIS_GUI_HDRS providers/sensorthings/qgssensorthingsguiprovider.h providers/sensorthings/qgssensorthingssourceselect.h providers/sensorthings/qgssensorthingssourcewidget.h + providers/sensorthings/qgssensorthingssubseteditor.h providers/vtpkvectortiles/qgsvtpkvectortileguiprovider.h providers/vtpkvectortiles/qgsvtpkvectortilesourcewidget.h diff --git a/src/gui/providers/sensorthings/qgssensorthingsguiprovider.cpp b/src/gui/providers/sensorthings/qgssensorthingsguiprovider.cpp index d9e4997ba41..eba10eaabe3 100644 --- a/src/gui/providers/sensorthings/qgssensorthingsguiprovider.cpp +++ b/src/gui/providers/sensorthings/qgssensorthingsguiprovider.cpp @@ -30,6 +30,9 @@ #include "qgssensorthingsprovider.h" #include "qgssensorthingsdataitemguiprovider.h" #include "qgsapplication.h" +#include "qgssubsetstringeditorprovider.h" +#include "qgssensorthingssubseteditor.h" +#include "qgsvectorlayer.h" // // QgsSensorThingsSourceSelectProvider @@ -112,4 +115,34 @@ QList QgsSensorThingsProviderGuiMetadata::dataItemGuiP return { new QgsSensorThingsDataItemGuiProvider() }; } +class QgsSensorThingsSubsetStringEditorProvider: public QgsSubsetStringEditorProvider +{ + public: + + QString providerKey() const override { return QgsSensorThingsProvider::SENSORTHINGS_PROVIDER_KEY; } + + bool canHandleLayer( QgsVectorLayer *layer ) const override + { + QgsDataProvider *provider = layer->dataProvider(); + return static_cast< bool >( qobject_cast( provider ) ); + } + + QgsSubsetStringEditorInterface *createDialog( QgsVectorLayer *layer, QWidget *parent, Qt::WindowFlags fl ) override + { + QgsDataProvider *provider = layer->dataProvider(); + QgsSensorThingsProvider *sensorThingsProvider = qobject_cast( provider ); + if ( !sensorThingsProvider ) + return nullptr; + + return new QgsSensorThingsSubsetEditor( layer, QgsFields(), parent, fl ); + } +}; + + +QList QgsSensorThingsProviderGuiMetadata::subsetStringEditorProviders() +{ + return QList() + << new QgsSensorThingsSubsetStringEditorProvider; +} + ///@endcond diff --git a/src/gui/providers/sensorthings/qgssensorthingsguiprovider.h b/src/gui/providers/sensorthings/qgssensorthingsguiprovider.h index 05124977e96..ce24861466b 100644 --- a/src/gui/providers/sensorthings/qgssensorthingsguiprovider.h +++ b/src/gui/providers/sensorthings/qgssensorthingsguiprovider.h @@ -53,6 +53,8 @@ class QgsSensorThingsProviderGuiMetadata: public QgsProviderGuiMetadata QList sourceSelectProviders() override; QList sourceWidgetProviders() override; QList dataItemGuiProviders() override; + QList subsetStringEditorProviders() override; + }; ///@endcond diff --git a/src/gui/providers/sensorthings/qgssensorthingssubseteditor.cpp b/src/gui/providers/sensorthings/qgssensorthingssubseteditor.cpp new file mode 100644 index 00000000000..c301ebf44b7 --- /dev/null +++ b/src/gui/providers/sensorthings/qgssensorthingssubseteditor.cpp @@ -0,0 +1,158 @@ +/*************************************************************************** + qgssensorthingssubseteditor.cpp + -------------------------------------- + Date : February 2024 + Copyright : (C) 2024 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 "qgssensorthingssubseteditor.h" +#include "qgsvectorlayer.h" +#include "qgscodeeditor.h" +#include "qgsfieldproxymodel.h" +#include "qgsfieldmodel.h" + +#include +#include +#include +#include + +///@cond PRIVATE + +QgsSensorThingsSubsetEditor::QgsSensorThingsSubsetEditor( QgsVectorLayer *layer, const QgsFields &fields, QWidget *parent, Qt::WindowFlags fl ) + : QgsSubsetStringEditorInterface( parent, fl ) + , mLayer( layer ) + , mFields( ( layer && fields.isEmpty() ) ? layer->fields() : fields ) +{ + setupUi( this ); + + mSubsetEditor = new QgsCodeEditor(); + mSubsetEditor->setWrapMode( QsciScintilla::WrapWord ); + + QVBoxLayout *vl = new QVBoxLayout(); + vl->addWidget( mSubsetEditor ); + mEditorGroupBox->setLayout( vl ); + + mModelFields = new QgsFieldProxyModel(); + mModelFields->setFilters( QgsFieldProxyModel::Filter::AllTypes | QgsFieldProxyModel::Filter::OriginProvider ); + mModelFields->sourceFieldModel()->setFields( mFields ); + lstFields->setModel( mModelFields ); + lstFields->setViewMode( QListView::ListMode ); + lstFields->setUniformItemSizes( true ); + lstFields->setAlternatingRowColors( true ); + lstFields->setSelectionBehavior( QAbstractItemView::SelectRows ); + + QFont boldFont = font(); + boldFont.setBold( true ); + mLabelComparisons->setFont( boldFont ); + mLabelLogical->setFont( boldFont ); + mLabelArithmetic->setFont( boldFont ); + + mButtonEq->setToolTip( tr( "Equal" ) ); + mButtonEq->setProperty( "expression", " eq " ); + mButtonNe->setToolTip( tr( "Not equal" ) ); + mButtonNe->setProperty( "expression", " ne " ); + mButtonGt->setToolTip( tr( "Greater than" ) ); + mButtonGt->setProperty( "expression", " gt " ); + mButtonGe->setToolTip( tr( "Greater than or equal" ) ); + mButtonGe->setProperty( "expression", " ge " ); + mButtonLt->setToolTip( tr( "Less than" ) ); + mButtonLt->setProperty( "expression", " lt " ); + mButtonLe->setToolTip( tr( "Less than or equal" ) ); + mButtonLe->setProperty( "expression", " le " ); + mButtonAnd->setToolTip( tr( "Logical and" ) ); + mButtonAnd->setProperty( "expression", " and " ); + mButtonOr->setToolTip( tr( "Logical or" ) ); + mButtonOr->setProperty( "expression", " or " ); + mButtonNot->setToolTip( tr( "Logical negation" ) ); + mButtonNot->setProperty( "expression", " not " ); + mButtonAdd->setToolTip( tr( "Addition" ) ); + mButtonAdd->setProperty( "expression", " add " ); + mButtonSub->setToolTip( tr( "Subtraction" ) ); + mButtonSub->setProperty( "expression", " sub " ); + mButtonMul->setToolTip( tr( "Multiplication" ) ); + mButtonMul->setProperty( "expression", " mul " ); + mButtonDiv->setToolTip( tr( "Division" ) ); + mButtonDiv->setProperty( "expression", " div " ); + mButtonMod->setToolTip( tr( "Modulo" ) ); + mButtonMod->setProperty( "expression", " mod " ); + + if ( mLayer ) + lblDataUri->setText( tr( "Set filter on %1" ).arg( mLayer->name() ) ); + else + lblDataUri->setText( tr( "Set filter for layer" ) ); + + connect( mButtonBox->button( QDialogButtonBox::Reset ), &QPushButton::clicked, this, &QgsSensorThingsSubsetEditor::reset ); + connect( mButtonBox, &QDialogButtonBox::accepted, this, &QgsSensorThingsSubsetEditor::accept ); + connect( mButtonBox, &QDialogButtonBox::rejected, this, &QgsSensorThingsSubsetEditor::reject ); + + connect( lstFields, &QListView::doubleClicked, this, &QgsSensorThingsSubsetEditor::lstFieldsDoubleClicked ); + + for ( QPushButton *button : + { + mButtonEq, + mButtonNe, + mButtonGt, + mButtonGe, + mButtonLt, + mButtonLe, + mButtonAnd, + mButtonOr, + mButtonNot, + mButtonAdd, + mButtonSub, + mButtonMul, + mButtonDiv, + mButtonMod + } ) + { + connect( button, &QPushButton::clicked, this, [this, button] + { + mSubsetEditor->insertText( button->property( "expression" ).toString() ); + mSubsetEditor->setFocus(); + } ); + + } +} + +QString QgsSensorThingsSubsetEditor::subsetString() const +{ + return mSubsetEditor->text(); +} + +void QgsSensorThingsSubsetEditor::setSubsetString( const QString &subsetString ) +{ + mSubsetEditor->setText( subsetString ); +} + +void QgsSensorThingsSubsetEditor::accept() +{ + if ( mLayer ) + { + mLayer->setSubsetString( subsetString() ); + } + QDialog::accept(); +} + +void QgsSensorThingsSubsetEditor::reset() +{ + mSubsetEditor->clear(); +} + +void QgsSensorThingsSubsetEditor::lstFieldsDoubleClicked( const QModelIndex &index ) +{ + mSubsetEditor->insertText( mModelFields->data( index, static_cast< int >( QgsFieldModel::CustomRole::FieldName ) ).toString() ); + mSubsetEditor->setFocus(); +} + + +///@endcond diff --git a/src/gui/providers/sensorthings/qgssensorthingssubseteditor.h b/src/gui/providers/sensorthings/qgssensorthingssubseteditor.h new file mode 100644 index 00000000000..9009fc4cb19 --- /dev/null +++ b/src/gui/providers/sensorthings/qgssensorthingssubseteditor.h @@ -0,0 +1,61 @@ +/*************************************************************************** + qgssensorthingssubseteditor.h + -------------------------------------- + Date : February 2024 + Copyright : (C) 2024 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. * + * * + ***************************************************************************/ +#ifndef QGSSENSORTHINGSSUBSETEDITOR_H +#define QGSSENSORTHINGSSUBSETEDITOR_H + +#include "qgis.h" +#include "ui_qgssensorthingssubseteditorbase.h" +#include "qgssubsetstringeditorinterface.h" +#include "qgsfields.h" +#include +#include + +class QgsVectorLayer; +class QgsCodeEditor; +class QgsFieldProxyModel; + +///@cond PRIVATE +#define SIP_NO_FILE + +class QgsSensorThingsSubsetEditor : public QgsSubsetStringEditorInterface, protected Ui::QgsSensorThingsSubsetEditorBase +{ + Q_OBJECT + + public: + QgsSensorThingsSubsetEditor( QgsVectorLayer *layer = nullptr, + const QgsFields &fields = QgsFields(), + QWidget *parent SIP_TRANSFERTHIS = nullptr, + Qt::WindowFlags fl = QgsGuiUtils::ModalDialogFlags ); + QString subsetString() const override; + void setSubsetString( const QString &subsetString ) override; + + private slots: + void accept() override; + void reset(); + void lstFieldsDoubleClicked( const QModelIndex &index ); + private: + + QgsCodeEditor *mSubsetEditor = nullptr; + + QPointer< QgsVectorLayer > mLayer; + QgsFields mFields; + + QgsFieldProxyModel *mModelFields = nullptr; +}; + +///@endcond +#endif // QGSSENSORTHINGSSUBSETEDITOR_H diff --git a/src/ui/qgssensorthingssubseteditorbase.ui b/src/ui/qgssensorthingssubseteditorbase.ui new file mode 100644 index 00000000000..04ce00c1682 --- /dev/null +++ b/src/ui/qgssensorthingssubseteditorbase.ui @@ -0,0 +1,252 @@ + + + QgsSensorThingsSubsetEditorBase + + + + 0 + 0 + 816 + 740 + + + + OGC SensorThings Data Filter + + + + + + Datasource + + + + + + + + 0 + 0 + + + + Fields + + + + 11 + + + 11 + + + 11 + + + 11 + + + + + <html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">List of fields in this vector file</p></body></html> + + + + + + + + + + Operators + + + + 11 + + + 11 + + + 11 + + + 11 + + + + + or + + + + + + + gt + + + + + + + le + + + + + + + and + + + + + + + eq + + + + + + + ne + + + + + + + not + + + + + + + Comparisons + + + + + + + add + + + + + + + Logical operators + + + + + + + ge + + + + + + + lt + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Arithmetic + + + + + + + sub + + + + + + + mul + + + + + + + div + + + + + + + mod + + + + + + + + + + + 0 + 0 + + + + OGC SensorThings Filter Expression + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok|QDialogButtonBox::Reset + + + false + + + + + + + + QgsCollapsibleGroupBox + QGroupBox +
qgscollapsiblegroupbox.h
+ 1 +
+
+ + +