mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-14 00:07:35 -04:00
allow QgsFeatureListComboBox to handle multiple keys
This commit is contained in:
parent
8cdfc2554d
commit
a5574eb96b
@ -26,6 +26,7 @@ Features are fetched asynchronously.
|
||||
enum Role
|
||||
{
|
||||
IdentifierValueRole,
|
||||
IdentifierValuesRole,
|
||||
ValueRole
|
||||
};
|
||||
|
||||
@ -103,28 +104,69 @@ Can be used for spatial filtering etc.
|
||||
Indicator if the model is currently performing any feature iteration in the background.
|
||||
%End
|
||||
|
||||
QString identifierField() const;
|
||||
QString identifierField() const;
|
||||
%Docstring
|
||||
The identifier field should be a unique field that can be used to identify individual features.
|
||||
It is normally set to the primary key of the layer.
|
||||
If there are several identifier fields defined, the behavior is not guaranteed
|
||||
|
||||
.. deprecated:: since QGIS 3.10 use identifierFields instead
|
||||
%End
|
||||
|
||||
void setIdentifierField( const QString &identifierField );
|
||||
QStringList identifierFields() const;
|
||||
%Docstring
|
||||
The identifier field should be a unique field that can be used to identify individual features.
|
||||
It is normally set to the primary key of the layer.
|
||||
|
||||
.. versionadded:: 3.10
|
||||
%End
|
||||
|
||||
QVariant extraIdentifierValue() const;
|
||||
void setIdentifierField( const QString &identifierField );
|
||||
%Docstring
|
||||
The identifier field should be a unique field that can be used to identify individual features.
|
||||
It is normally set to the primary key of the layer.
|
||||
|
||||
.. deprecated:: since QGIS 3.10
|
||||
%End
|
||||
|
||||
void setIdentifierFields( const QStringList &identifierFields );
|
||||
%Docstring
|
||||
The identifier field should be a unique field that can be used to identify individual features.
|
||||
It is normally set to the primary key of the layer.
|
||||
|
||||
.. versionadded:: 3.10
|
||||
%End
|
||||
|
||||
QVariant extraIdentifierValue() const;
|
||||
%Docstring
|
||||
Allows specifying one value that does not need to match the filter criteria but will
|
||||
still be available in the model.
|
||||
|
||||
.. deprecated:: since QGIS 3.10
|
||||
%End
|
||||
|
||||
void setExtraIdentifierValue( const QVariant &extraIdentifierValue );
|
||||
QVariantList extraIdentifierValues() const;
|
||||
%Docstring
|
||||
Allows specifying one value that does not need to match the filter criteria but will
|
||||
still be available in the model.
|
||||
|
||||
.. versionadded:: 3.10
|
||||
%End
|
||||
|
||||
void setExtraIdentifierValue( const QVariant &extraIdentifierValue );
|
||||
%Docstring
|
||||
Allows specifying one value that does not need to match the filter criteria but will
|
||||
still be available in the model.
|
||||
|
||||
.. deprecated:: since QGIS 3.10
|
||||
%End
|
||||
|
||||
void setExtraIdentifierValues( const QVariantList &extraIdentifierValues );
|
||||
%Docstring
|
||||
Allows specifying one value that does not need to match the filter criteria but will
|
||||
still be available in the model.
|
||||
|
||||
.. versionadded:: 3.10
|
||||
%End
|
||||
|
||||
int extraIdentifierValueIndex() const;
|
||||
|
@ -9,6 +9,7 @@
|
||||
|
||||
|
||||
|
||||
|
||||
class QgsFeatureListComboBox : QComboBox
|
||||
{
|
||||
%Docstring
|
||||
@ -38,6 +39,13 @@ The layer from which features should be listed.
|
||||
void setSourceLayer( QgsVectorLayer *sourceLayer );
|
||||
%Docstring
|
||||
The layer from which features should be listed.
|
||||
%End
|
||||
|
||||
void setCurrentFeature( const QgsFeature &feature );
|
||||
%Docstring
|
||||
Sets the current index by using the given feature
|
||||
|
||||
.. versionadded:: 3.10
|
||||
%End
|
||||
|
||||
QString displayExpression() const;
|
||||
@ -74,16 +82,37 @@ This can be used to integrate additional spatial or other constraints.
|
||||
TODO!
|
||||
%End
|
||||
|
||||
QVariant identifierValue() const;
|
||||
QVariant identifierValue() const /Deprecated/;
|
||||
%Docstring
|
||||
The identifier value of the currently selected feature. A value from the
|
||||
identifierField.
|
||||
|
||||
.. deprecated:: since QGIS 3.10
|
||||
%End
|
||||
|
||||
void setIdentifierValue( const QVariant &identifierValue );
|
||||
QVariantList identifierValues() const;
|
||||
%Docstring
|
||||
The identifier values of the currently selected feature. A value from the
|
||||
identifierField.
|
||||
|
||||
.. versionadded:: 3.10
|
||||
%End
|
||||
|
||||
|
||||
void setIdentifierValue( const QVariant &identifierValue ) /Deprecated/;
|
||||
%Docstring
|
||||
The identifier value of the currently selected feature. A value from the
|
||||
identifierField.
|
||||
|
||||
.. deprecated:: since QGIS 3.10 use setIdentifierValues
|
||||
%End
|
||||
|
||||
void setIdentifierValues( const QVariantList &identifierValues );
|
||||
%Docstring
|
||||
The identifier values of the currently selected feature. A value from the
|
||||
identifierFields.
|
||||
|
||||
.. versionadded:: 3.10
|
||||
%End
|
||||
|
||||
QgsFeatureRequest currentFeatureRequest() const;
|
||||
@ -102,16 +131,36 @@ Determines if a NULL value should be available in the list.
|
||||
Determines if a NULL value should be available in the list.
|
||||
%End
|
||||
|
||||
QString identifierField() const;
|
||||
QString identifierField() const /Deprecated/;
|
||||
%Docstring
|
||||
Field name that will be used to uniquely identify the current feature.
|
||||
Normally the primary key of the layer.
|
||||
|
||||
.. deprecated:: since QGIS 3.10
|
||||
%End
|
||||
|
||||
void setIdentifierField( const QString &identifierField );
|
||||
QStringList identifierFields() const;
|
||||
%Docstring
|
||||
Field name that will be used to uniquely identify the current feature.
|
||||
Normally the primary key of the layer.
|
||||
|
||||
.. versionadded:: 3.10
|
||||
%End
|
||||
|
||||
void setIdentifierField( const QString &identifierField ) /Deprecated/;
|
||||
%Docstring
|
||||
Field name that will be used to uniquely identify the current feature.
|
||||
Normally the primary key of the layer.
|
||||
|
||||
.. deprecated:: since QGIS 3.10
|
||||
%End
|
||||
|
||||
void setIdentifierFields( const QStringList &identifierFields );
|
||||
%Docstring
|
||||
Field name that will be used to uniquely identify the current feature.
|
||||
Normally the primary key of the layer.
|
||||
|
||||
.. versionadded:: 3.10
|
||||
%End
|
||||
|
||||
QModelIndex currentModelIndex() const;
|
||||
@ -170,6 +219,8 @@ Determines if a NULL value should be available in the list.
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
/************************************************************************
|
||||
* This file has been generated automatically from *
|
||||
* *
|
||||
|
@ -1,6 +1,5 @@
|
||||
/***************************************************************************
|
||||
qgsfeaturefiltermodel.cpp - QgsFeatureFilterModel
|
||||
|
||||
---------------------
|
||||
begin : 10.3.2017
|
||||
copyright : (C) 2017 by Matthias Kuhn
|
||||
@ -27,7 +26,7 @@ QgsFeatureFilterModel::QgsFeatureFilterModel( QObject *parent )
|
||||
mReloadTimer.setInterval( 100 );
|
||||
mReloadTimer.setSingleShot( true );
|
||||
connect( &mReloadTimer, &QTimer::timeout, this, &QgsFeatureFilterModel::scheduledReload );
|
||||
setExtraIdentifierValueUnguarded( QVariant() );
|
||||
setExtraIdentifierValuesUnguarded( QVariantList() );
|
||||
}
|
||||
|
||||
QgsFeatureFilterModel::~QgsFeatureFilterModel()
|
||||
@ -102,6 +101,14 @@ bool QgsFeatureFilterModel::isLoading() const
|
||||
return mGatherer;
|
||||
}
|
||||
|
||||
QString QgsFeatureFilterModel::identifierField() const
|
||||
{
|
||||
if ( mIdentifierFields.isEmpty() )
|
||||
return QString();
|
||||
else
|
||||
return mIdentifierFields.at( 0 );
|
||||
}
|
||||
|
||||
QModelIndex QgsFeatureFilterModel::index( int row, int column, const QModelIndex &parent ) const
|
||||
{
|
||||
Q_UNUSED( parent )
|
||||
@ -140,30 +147,42 @@ QVariant QgsFeatureFilterModel::data( const QModelIndex &index, int role ) const
|
||||
return mEntries.value( index.row() ).value;
|
||||
|
||||
case IdentifierValueRole:
|
||||
return mEntries.value( index.row() ).identifierValue;
|
||||
{
|
||||
QVariantList values = mEntries.value( index.row() ).identifierValues;
|
||||
return values.isEmpty() ? QVariant() : values.at( 0 );
|
||||
}
|
||||
|
||||
case IdentifierValuesRole:
|
||||
return mEntries.value( index.row() ).identifierValues;
|
||||
|
||||
case Qt::BackgroundColorRole:
|
||||
case Qt::TextColorRole:
|
||||
case Qt::DecorationRole:
|
||||
case Qt::FontRole:
|
||||
{
|
||||
if ( mEntries.value( index.row() ).identifierValue.isNull() )
|
||||
bool isNull = true;
|
||||
for ( const QVariant &value : mEntries.value( index.row() ).identifierValues )
|
||||
{
|
||||
if ( !value.isNull() )
|
||||
{
|
||||
isNull = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( isNull )
|
||||
{
|
||||
// Representation for NULL value
|
||||
if ( role == Qt::TextColorRole )
|
||||
{
|
||||
return QBrush( QColor( Qt::gray ) );
|
||||
}
|
||||
else if ( role == Qt::FontRole )
|
||||
if ( role == Qt::FontRole )
|
||||
{
|
||||
QFont font = QFont();
|
||||
if ( index.row() == mExtraIdentifierValueIndex )
|
||||
font.setBold( true );
|
||||
|
||||
if ( mEntries.value( index.row() ).identifierValue.isNull() )
|
||||
{
|
||||
else
|
||||
font.setItalic( true );
|
||||
}
|
||||
return font;
|
||||
}
|
||||
}
|
||||
@ -197,7 +216,7 @@ void QgsFeatureFilterModel::updateCompleter()
|
||||
QVector<Entry> entries = mGatherer->entries();
|
||||
|
||||
if ( mExtraIdentifierValueIndex == -1 )
|
||||
setExtraIdentifierValueUnguarded( QVariant() );
|
||||
setExtraIdentifierValuesUnguarded( QVariantList() );
|
||||
|
||||
// Only reloading the current entry?
|
||||
if ( mGatherer->data().toBool() )
|
||||
@ -225,7 +244,9 @@ void QgsFeatureFilterModel::updateCompleter()
|
||||
std::sort( entries.begin(), entries.end(), []( const Entry & a, const Entry & b ) { return a.value.localeAwareCompare( b.value ) < 0; } );
|
||||
|
||||
if ( mAllowNull )
|
||||
entries.prepend( Entry( QVariant( QVariant::Int ), QgsApplication::nullRepresentation(), QgsFeature() ) );
|
||||
{
|
||||
entries.prepend( nullEntry() );
|
||||
}
|
||||
|
||||
const int newEntriesSize = entries.size();
|
||||
|
||||
@ -235,7 +256,7 @@ void QgsFeatureFilterModel::updateCompleter()
|
||||
{
|
||||
for ( int i = 0; i < newEntriesSize; ++i )
|
||||
{
|
||||
if ( entries.at( i ).identifierValue == mExtraIdentifierValue )
|
||||
if ( entries.at( i ).identifierValues == mExtraIdentifierValues )
|
||||
{
|
||||
currentEntryInNewList = i;
|
||||
mEntries.replace( mExtraIdentifierValueIndex, entries.at( i ) );
|
||||
@ -274,7 +295,7 @@ void QgsFeatureFilterModel::updateCompleter()
|
||||
beginInsertRows( QModelIndex(), 1, entries.size() + 1 );
|
||||
mEntries += entries;
|
||||
endInsertRows();
|
||||
setExtraIdentifierValueIndex( 0 );
|
||||
setExtraIdentifierValuesIndex( 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -294,7 +315,7 @@ void QgsFeatureFilterModel::updateCompleter()
|
||||
beginInsertRows( QModelIndex(), currentEntryInNewList + 1, newEntriesSize - currentEntryInNewList - 1 );
|
||||
mEntries += entries.mid( currentEntryInNewList + 1 );
|
||||
endInsertRows();
|
||||
setExtraIdentifierValueIndex( currentEntryInNewList );
|
||||
setExtraIdentifierValuesIndex( currentEntryInNewList );
|
||||
}
|
||||
|
||||
emit filterJobCompleted();
|
||||
@ -331,7 +352,19 @@ void QgsFeatureFilterModel::scheduledReload()
|
||||
|
||||
if ( mShouldReloadCurrentFeature )
|
||||
{
|
||||
request.setFilterExpression( QStringLiteral( "%1 = %2" ).arg( QgsExpression::quotedColumnRef( mIdentifierField ), QgsExpression::quotedValue( mExtraIdentifierValue ) ) );
|
||||
QStringList conditions;
|
||||
for ( int i = 0; i < mIdentifierFields.count(); i++ )
|
||||
{
|
||||
if ( i >= mExtraIdentifierValues.count() )
|
||||
{
|
||||
conditions << QgsExpression::createFieldEqualityExpression( mIdentifierFields.at( i ), QVariant() );
|
||||
}
|
||||
else
|
||||
{
|
||||
conditions << QgsExpression::createFieldEqualityExpression( mIdentifierFields.at( i ), mExtraIdentifierValues.at( i ) );
|
||||
}
|
||||
}
|
||||
request.setFilterExpression( conditions.join( QStringLiteral( " AND " ) ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -350,13 +383,14 @@ void QgsFeatureFilterModel::scheduledReload()
|
||||
QSet<QString> attributes;
|
||||
if ( request.filterExpression() )
|
||||
attributes = request.filterExpression()->referencedColumns();
|
||||
attributes << mIdentifierField;
|
||||
for ( const QString &fieldName : qgis::as_const( mIdentifierFields ) )
|
||||
attributes << fieldName;
|
||||
request.setSubsetOfAttributes( attributes, mSourceLayer->fields() );
|
||||
request.setFlags( QgsFeatureRequest::NoGeometry );
|
||||
|
||||
request.setLimit( QgsSettings().value( QStringLiteral( "maxEntriesRelationWidget" ), 100, QgsSettings::Gui ).toInt() );
|
||||
|
||||
mGatherer = new QgsFieldExpressionValuesGatherer( mSourceLayer, mDisplayExpression, mIdentifierField, request );
|
||||
mGatherer = new QgsFieldExpressionValuesGatherer( mSourceLayer, mDisplayExpression, mIdentifierFields, request );
|
||||
mGatherer->setData( mShouldReloadCurrentFeature );
|
||||
|
||||
connect( mGatherer, &QgsFieldExpressionValuesGatherer::collectedValues, this, &QgsFeatureFilterModel::updateCompleter );
|
||||
@ -393,7 +427,7 @@ QSet<QString> QgsFeatureFilterModel::requestedAttributes() const
|
||||
return requestedAttrs;
|
||||
}
|
||||
|
||||
void QgsFeatureFilterModel::setExtraIdentifierValueIndex( int index, bool force )
|
||||
void QgsFeatureFilterModel::setExtraIdentifierValuesIndex( int index, bool force )
|
||||
{
|
||||
if ( mExtraIdentifierValueIndex == index && !force )
|
||||
return;
|
||||
@ -408,18 +442,16 @@ void QgsFeatureFilterModel::reloadCurrentFeature()
|
||||
mReloadTimer.start();
|
||||
}
|
||||
|
||||
void QgsFeatureFilterModel::setExtraIdentifierValueUnguarded( const QVariant &extraIdentifierValue )
|
||||
void QgsFeatureFilterModel::setExtraIdentifierValuesUnguarded( const QVariantList &extraIdentifierValues )
|
||||
{
|
||||
const QVector<Entry> entries = mEntries;
|
||||
|
||||
int index = 0;
|
||||
for ( const Entry &entry : entries )
|
||||
{
|
||||
if ( entry.identifierValue == extraIdentifierValue
|
||||
&& entry.identifierValue.isNull() == extraIdentifierValue.isNull()
|
||||
&& entry.identifierValue.isValid() == extraIdentifierValue.isValid() )
|
||||
if ( entry.identifierValues == extraIdentifierValues )
|
||||
{
|
||||
setExtraIdentifierValueIndex( index );
|
||||
setExtraIdentifierValuesIndex( index );
|
||||
break;
|
||||
}
|
||||
|
||||
@ -430,18 +462,37 @@ void QgsFeatureFilterModel::setExtraIdentifierValueUnguarded( const QVariant &ex
|
||||
if ( mExtraIdentifierValueIndex != index )
|
||||
{
|
||||
beginInsertRows( QModelIndex(), 0, 0 );
|
||||
if ( extraIdentifierValue.isNull() )
|
||||
mEntries.prepend( Entry( QVariant( QVariant::Int ), QgsApplication::nullRepresentation( ), QgsFeature() ) );
|
||||
if ( extraIdentifierValues.isEmpty() )
|
||||
{
|
||||
mEntries.prepend( nullEntry() );
|
||||
}
|
||||
else
|
||||
mEntries.prepend( Entry( extraIdentifierValue, QStringLiteral( "(%1)" ).arg( extraIdentifierValue.toString() ), QgsFeature() ) );
|
||||
{
|
||||
QStringList values;
|
||||
for ( const QVariant &v : qgis::as_const( extraIdentifierValues ) )
|
||||
values << QStringLiteral( "(%1)" ).arg( v.toString() );
|
||||
|
||||
mEntries.prepend( Entry( extraIdentifierValues, values.join( QStringLiteral( " " ) ), QgsFeature() ) );
|
||||
}
|
||||
endInsertRows();
|
||||
|
||||
setExtraIdentifierValueIndex( 0, true );
|
||||
setExtraIdentifierValuesIndex( 0, true );
|
||||
|
||||
reloadCurrentFeature();
|
||||
}
|
||||
}
|
||||
|
||||
QgsFeatureFilterModel::Entry QgsFeatureFilterModel::nullEntry()
|
||||
{
|
||||
QVariantList nullAttributes;
|
||||
for ( const QString &fieldName : mIdentifierFields )
|
||||
{
|
||||
int idx = mSourceLayer->fields().indexOf( fieldName );
|
||||
nullAttributes << QVariant( mSourceLayer->fields().at( idx ).type() );
|
||||
}
|
||||
return Entry( nullAttributes, QgsApplication::nullRepresentation(), QgsFeature() );
|
||||
}
|
||||
|
||||
QgsConditionalStyle QgsFeatureFilterModel::featureStyle( const QgsFeature &feature ) const
|
||||
{
|
||||
if ( !mSourceLayer )
|
||||
@ -505,18 +556,24 @@ int QgsFeatureFilterModel::extraIdentifierValueIndex() const
|
||||
return mExtraIdentifierValueIndex;
|
||||
}
|
||||
|
||||
QString QgsFeatureFilterModel::identifierField() const
|
||||
QStringList QgsFeatureFilterModel::identifierFields() const
|
||||
{
|
||||
return mIdentifierField;
|
||||
return mIdentifierFields;
|
||||
}
|
||||
|
||||
void QgsFeatureFilterModel::setIdentifierField( const QString &identifierField )
|
||||
{
|
||||
if ( mIdentifierField == identifierField )
|
||||
setIdentifierFields( QStringList() << identifierField );
|
||||
}
|
||||
|
||||
void QgsFeatureFilterModel::setIdentifierFields( const QStringList &identifierFields )
|
||||
{
|
||||
if ( mIdentifierFields == identifierFields )
|
||||
return;
|
||||
|
||||
mIdentifierField = identifierField;
|
||||
mIdentifierFields = identifierFields;
|
||||
emit identifierFieldChanged();
|
||||
setExtraIdentifierValues( QVariantList() );
|
||||
}
|
||||
|
||||
void QgsFeatureFilterModel::reload()
|
||||
@ -526,12 +583,25 @@ void QgsFeatureFilterModel::reload()
|
||||
|
||||
QVariant QgsFeatureFilterModel::extraIdentifierValue() const
|
||||
{
|
||||
return mExtraIdentifierValue;
|
||||
if ( mExtraIdentifierValues.isEmpty() )
|
||||
return QVariant();
|
||||
else
|
||||
return mExtraIdentifierValues.at( 0 );
|
||||
}
|
||||
|
||||
QVariantList QgsFeatureFilterModel::extraIdentifierValues() const
|
||||
{
|
||||
return mExtraIdentifierValues;
|
||||
}
|
||||
|
||||
void QgsFeatureFilterModel::setExtraIdentifierValue( const QVariant &extraIdentifierValue )
|
||||
{
|
||||
if ( qgsVariantEqual( extraIdentifierValue, mExtraIdentifierValue ) && mExtraIdentifierValue.isValid() )
|
||||
setExtraIdentifierValues( QVariantList() << extraIdentifierValue );
|
||||
}
|
||||
|
||||
void QgsFeatureFilterModel::setExtraIdentifierValues( const QVariantList &extraIdentifierValues )
|
||||
{
|
||||
if ( extraIdentifierValues == mExtraIdentifierValues && !mExtraIdentifierValues.isEmpty() )
|
||||
return;
|
||||
|
||||
if ( mIsSettingExtraIdentifierValue )
|
||||
@ -539,9 +609,9 @@ void QgsFeatureFilterModel::setExtraIdentifierValue( const QVariant &extraIdenti
|
||||
|
||||
mIsSettingExtraIdentifierValue = true;
|
||||
|
||||
mExtraIdentifierValue = extraIdentifierValue;
|
||||
mExtraIdentifierValues = extraIdentifierValues;
|
||||
|
||||
setExtraIdentifierValueUnguarded( extraIdentifierValue );
|
||||
setExtraIdentifierValuesUnguarded( extraIdentifierValues );
|
||||
|
||||
mIsSettingExtraIdentifierValue = false;
|
||||
|
||||
|
@ -1,6 +1,5 @@
|
||||
/***************************************************************************
|
||||
qgsfeaturefiltermodel.h - QgsFeatureFilterModel
|
||||
|
||||
---------------------
|
||||
begin : 10.3.2017
|
||||
copyright : (C) 2017 by Matthias Kuhn
|
||||
@ -61,7 +60,8 @@ class CORE_EXPORT QgsFeatureFilterModel : public QAbstractItemModel
|
||||
*/
|
||||
enum Role
|
||||
{
|
||||
IdentifierValueRole = Qt::UserRole, //!< Used to retrieve the identifierValue (primary key) of a feature.
|
||||
IdentifierValueRole = Qt::UserRole, //!< \deprecated Use IdentifierValuesRole instead
|
||||
IdentifierValuesRole, //!< Used to retrieve the identifierValues (primary keys) of a feature.
|
||||
ValueRole //!< Used to retrieve the displayExpression of a feature.
|
||||
};
|
||||
|
||||
@ -137,26 +137,59 @@ class CORE_EXPORT QgsFeatureFilterModel : public QAbstractItemModel
|
||||
/**
|
||||
* The identifier field should be a unique field that can be used to identify individual features.
|
||||
* It is normally set to the primary key of the layer.
|
||||
* If there are several identifier fields defined, the behavior is not guaranteed
|
||||
* \deprecated since QGIS 3.10 use identifierFields instead
|
||||
*/
|
||||
QString identifierField() const;
|
||||
Q_DECL_DEPRECATED QString identifierField() const;
|
||||
|
||||
/**
|
||||
* The identifier field should be a unique field that can be used to identify individual features.
|
||||
* It is normally set to the primary key of the layer.
|
||||
* \since QGIS 3.10
|
||||
*/
|
||||
void setIdentifierField( const QString &identifierField );
|
||||
QStringList identifierFields() const;
|
||||
|
||||
/**
|
||||
* The identifier field should be a unique field that can be used to identify individual features.
|
||||
* It is normally set to the primary key of the layer.
|
||||
* \deprecated since QGIS 3.10
|
||||
*/
|
||||
Q_DECL_DEPRECATED void setIdentifierField( const QString &identifierField );
|
||||
|
||||
/**
|
||||
* The identifier field should be a unique field that can be used to identify individual features.
|
||||
* It is normally set to the primary key of the layer.
|
||||
* \since QGIS 3.10
|
||||
*/
|
||||
void setIdentifierFields( const QStringList &identifierFields );
|
||||
|
||||
/**
|
||||
* Allows specifying one value that does not need to match the filter criteria but will
|
||||
* still be available in the model.
|
||||
* \deprecated since QGIS 3.10
|
||||
*/
|
||||
QVariant extraIdentifierValue() const;
|
||||
Q_DECL_DEPRECATED QVariant extraIdentifierValue() const;
|
||||
|
||||
/**
|
||||
* Allows specifying one value that does not need to match the filter criteria but will
|
||||
* still be available in the model.
|
||||
* \since QGIS 3.10
|
||||
*/
|
||||
void setExtraIdentifierValue( const QVariant &extraIdentifierValue );
|
||||
QVariantList extraIdentifierValues() const;
|
||||
|
||||
/**
|
||||
* Allows specifying one value that does not need to match the filter criteria but will
|
||||
* still be available in the model.
|
||||
* \deprecated since QGIS 3.10
|
||||
*/
|
||||
Q_DECL_DEPRECATED void setExtraIdentifierValue( const QVariant &extraIdentifierValue );
|
||||
|
||||
/**
|
||||
* Allows specifying one value that does not need to match the filter criteria but will
|
||||
* still be available in the model.
|
||||
* \since QGIS 3.10
|
||||
*/
|
||||
void setExtraIdentifierValues( const QVariantList &extraIdentifierValues );
|
||||
|
||||
/**
|
||||
* The index at which the extra identifier value is available within the model.
|
||||
@ -260,27 +293,28 @@ class CORE_EXPORT QgsFeatureFilterModel : public QAbstractItemModel
|
||||
|
||||
private:
|
||||
QSet<QString> requestedAttributes() const;
|
||||
void setExtraIdentifierValueIndex( int index, bool force = false );
|
||||
void setExtraIdentifierValuesIndex( int index, bool force = false );
|
||||
void setExtraValueDoesNotExist( bool extraValueDoesNotExist );
|
||||
void reload();
|
||||
void reloadCurrentFeature();
|
||||
void setExtraIdentifierValueUnguarded( const QVariant &extraIdentifierValue );
|
||||
void setExtraIdentifierValuesUnguarded( const QVariantList &extraIdentifierValues );
|
||||
struct Entry
|
||||
{
|
||||
Entry() = default;
|
||||
|
||||
Entry( const QVariant &_identifierValue, const QString &_value, const QgsFeature &_feature )
|
||||
: identifierValue( _identifierValue )
|
||||
Entry( const QVariantList &_identifierValues, const QString &_value, const QgsFeature &_feature )
|
||||
: identifierValues( _identifierValues )
|
||||
, value( _value )
|
||||
, feature( _feature )
|
||||
{}
|
||||
|
||||
QVariant identifierValue;
|
||||
QVariantList identifierValues;
|
||||
QString value;
|
||||
QgsFeature feature;
|
||||
|
||||
bool operator()( const Entry &lhs, const Entry &rhs ) const;
|
||||
};
|
||||
Entry nullEntry();
|
||||
|
||||
QgsConditionalStyle featureStyle( const QgsFeature &feature ) const;
|
||||
|
||||
@ -299,9 +333,8 @@ class CORE_EXPORT QgsFeatureFilterModel : public QAbstractItemModel
|
||||
bool mAllowNull = false;
|
||||
bool mIsSettingExtraIdentifierValue = false;
|
||||
|
||||
QString mIdentifierField;
|
||||
|
||||
QVariant mExtraIdentifierValue;
|
||||
QStringList mIdentifierFields;
|
||||
QVariantList mExtraIdentifierValues;
|
||||
|
||||
int mExtraIdentifierValueIndex = -1;
|
||||
|
||||
|
@ -1,6 +1,5 @@
|
||||
/***************************************************************************
|
||||
qgsfeaturefiltermodel_p - QgsFieldExpressionValuesGatherer
|
||||
|
||||
---------------------
|
||||
begin : 10.3.2017
|
||||
copyright : (C) 2017 by Matthias Kuhn
|
||||
@ -37,11 +36,14 @@ class QgsFieldExpressionValuesGatherer: public QThread
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
QgsFieldExpressionValuesGatherer( QgsVectorLayer *layer, const QString &displayExpression, const QString &identifierField, const QgsFeatureRequest &request = QgsFeatureRequest() )
|
||||
QgsFieldExpressionValuesGatherer( QgsVectorLayer *layer,
|
||||
const QString &displayExpression,
|
||||
const QStringList &identifierFields,
|
||||
const QgsFeatureRequest &request = QgsFeatureRequest() )
|
||||
: mSource( new QgsVectorLayerFeatureSource( layer ) )
|
||||
, mDisplayExpression( displayExpression )
|
||||
, mRequest( request )
|
||||
, mIdentifierField( identifierField )
|
||||
, mIdentifierFields( identifierFields )
|
||||
{
|
||||
}
|
||||
|
||||
@ -54,12 +56,17 @@ class QgsFieldExpressionValuesGatherer: public QThread
|
||||
mDisplayExpression.prepare( &mExpressionContext );
|
||||
|
||||
QgsFeature feat;
|
||||
const int attribute = mSource->fields().indexOf( mIdentifierField );
|
||||
QList<int> attributeIndexes;
|
||||
for ( const QString &fieldName : qgis::as_const( mIdentifierFields ) )
|
||||
attributeIndexes << mSource->fields().indexOf( fieldName );
|
||||
|
||||
while ( mIterator.nextFeature( feat ) )
|
||||
{
|
||||
mExpressionContext.setFeature( feat );
|
||||
mEntries.append( QgsFeatureFilterModel::Entry( feat.attribute( attribute ), mDisplayExpression.evaluate( &mExpressionContext ).toString(), feat ) );
|
||||
QVariantList attributes;
|
||||
for ( const int idx : attributeIndexes )
|
||||
attributes << feat.attribute( idx );
|
||||
mEntries.append( QgsFeatureFilterModel::Entry( attributes, mDisplayExpression.evaluate( &mExpressionContext ).toString(), feat ) );
|
||||
|
||||
if ( mWasCanceled )
|
||||
return;
|
||||
@ -120,7 +127,7 @@ class QgsFieldExpressionValuesGatherer: public QThread
|
||||
QgsFeatureIterator mIterator;
|
||||
bool mWasCanceled = false;
|
||||
QVector<QgsFeatureFilterModel::Entry> mEntries;
|
||||
QString mIdentifierField;
|
||||
QStringList mIdentifierFields;
|
||||
QVariant mData;
|
||||
};
|
||||
|
||||
|
@ -1,6 +1,5 @@
|
||||
/***************************************************************************
|
||||
qgsfieldlistcombobox.cpp - QgsFieldListComboBox
|
||||
|
||||
qgsfeaturelistcombobox.cpp - QgsFeatureListComboBox
|
||||
---------------------
|
||||
begin : 10.3.2017
|
||||
copyright : (C) 2017 by Matthias Kuhn
|
||||
@ -75,6 +74,17 @@ void QgsFeatureListComboBox::setSourceLayer( QgsVectorLayer *sourceLayer )
|
||||
mModel->setSourceLayer( sourceLayer );
|
||||
}
|
||||
|
||||
void QgsFeatureListComboBox::setCurrentFeature( const QgsFeature &feature )
|
||||
{
|
||||
QVariantList values;
|
||||
const QStringList fields = mModel->identifierFields();
|
||||
for ( const QString &field : fields )
|
||||
{
|
||||
values << feature.attribute( field );
|
||||
}
|
||||
setCurrentIndex( findData( values, QgsFeatureFilterModel::Role::IdentifierValueRole ) );
|
||||
}
|
||||
|
||||
QString QgsFeatureListComboBox::displayExpression() const
|
||||
{
|
||||
return mModel->displayExpression();
|
||||
@ -115,7 +125,7 @@ void QgsFeatureListComboBox::onCurrentIndexChanged( int i )
|
||||
if ( !mHasStoredEditState )
|
||||
mIsCurrentlyEdited = false;
|
||||
QModelIndex modelIndex = mModel->index( i, 0, QModelIndex() );
|
||||
mModel->setExtraIdentifierValue( mModel->data( modelIndex, QgsFeatureFilterModel::IdentifierValueRole ) );
|
||||
mModel->setExtraIdentifierValues( mModel->data( modelIndex, QgsFeatureFilterModel::IdentifierValuesRole ).toList() );
|
||||
mLineEdit->setText( mModel->data( modelIndex, QgsFeatureFilterModel::ValueRole ).toString() );
|
||||
mLineEdit->setFont( mModel->data( modelIndex, Qt::FontRole ).value<QFont>() );
|
||||
QPalette palette = mLineEdit->palette();
|
||||
@ -125,7 +135,7 @@ void QgsFeatureListComboBox::onCurrentIndexChanged( int i )
|
||||
|
||||
void QgsFeatureListComboBox::onActivated( QModelIndex modelIndex )
|
||||
{
|
||||
setIdentifierValue( mModel->data( modelIndex, QgsFeatureFilterModel::IdentifierValueRole ) );
|
||||
setIdentifierValues( mModel->data( modelIndex, QgsFeatureFilterModel::IdentifierValuesRole ).toList() );
|
||||
mLineEdit->setText( mModel->data( modelIndex, QgsFeatureFilterModel::ValueRole ).toString() );
|
||||
}
|
||||
|
||||
@ -175,12 +185,26 @@ void QgsFeatureListComboBox::onDataChanged( const QModelIndex &topLeft, const QM
|
||||
|
||||
QString QgsFeatureListComboBox::identifierField() const
|
||||
{
|
||||
return mModel->identifierField();
|
||||
QStringList list = mModel->identifierFields();
|
||||
if ( list.isEmpty() )
|
||||
return QString();
|
||||
else
|
||||
return list.at( 0 );
|
||||
}
|
||||
|
||||
QStringList QgsFeatureListComboBox::identifierFields() const
|
||||
{
|
||||
return mModel->identifierFields();
|
||||
}
|
||||
|
||||
void QgsFeatureListComboBox::setIdentifierField( const QString &identifierField )
|
||||
{
|
||||
mModel->setIdentifierField( identifierField );
|
||||
mModel->setIdentifierFields( QStringList() << identifierField );
|
||||
}
|
||||
|
||||
void QgsFeatureListComboBox::setIdentifierFields( const QStringList &identifierFields )
|
||||
{
|
||||
mModel->setIdentifierFields( identifierFields );
|
||||
}
|
||||
|
||||
QModelIndex QgsFeatureListComboBox::currentModelIndex() const
|
||||
@ -219,17 +243,46 @@ QVariant QgsFeatureListComboBox::identifierValue() const
|
||||
return mModel->extraIdentifierValue();
|
||||
}
|
||||
|
||||
QVariantList QgsFeatureListComboBox::identifierValues() const
|
||||
{
|
||||
return mModel->extraIdentifierValues();
|
||||
}
|
||||
|
||||
void QgsFeatureListComboBox::setIdentifierValue( const QVariant &identifierValue )
|
||||
{
|
||||
mModel->setExtraIdentifierValue( identifierValue );
|
||||
setIdentifierValues( QVariantList() << identifierValue );
|
||||
}
|
||||
|
||||
void QgsFeatureListComboBox::setIdentifierValues( const QVariantList &identifierValues )
|
||||
{
|
||||
mModel->setExtraIdentifierValues( identifierValues );
|
||||
}
|
||||
|
||||
QgsFeatureRequest QgsFeatureListComboBox::currentFeatureRequest() const
|
||||
{
|
||||
if ( mModel->extraIdentifierValue().isNull() )
|
||||
if ( mModel->extraIdentifierValues().isEmpty() )
|
||||
{
|
||||
return QgsFeatureRequest().setFilterFids( QgsFeatureIds() ); // NULL: Return a request that's guaranteed to not return anything
|
||||
}
|
||||
else
|
||||
return QgsFeatureRequest().setFilterExpression( QStringLiteral( "%1 = %2" ).arg( QgsExpression::quotedColumnRef( mModel->identifierField() ), QgsExpression::quotedValue( mModel->extraIdentifierValue() ) ) );
|
||||
{
|
||||
QStringList filtersAttrs;
|
||||
const QStringList identifierFields = mModel->identifierFields();
|
||||
const QVariantList values = mModel->extraIdentifierValues();
|
||||
for ( int i = 0; i < identifierFields.count(); i++ )
|
||||
{
|
||||
if ( i >= values.count() )
|
||||
{
|
||||
filtersAttrs << QgsExpression::createFieldEqualityExpression( identifierFields.at( i ), QVariant() );
|
||||
}
|
||||
else
|
||||
{
|
||||
filtersAttrs << QgsExpression::createFieldEqualityExpression( identifierFields.at( i ), values.at( i ) );
|
||||
}
|
||||
}
|
||||
const QString expression = filtersAttrs.join( QStringLiteral( " AND " ) );
|
||||
return QgsFeatureRequest().setFilterExpression( expression );
|
||||
}
|
||||
}
|
||||
|
||||
QString QgsFeatureListComboBox::filterExpression() const
|
||||
|
@ -1,6 +1,5 @@
|
||||
/***************************************************************************
|
||||
qgsfieldlistcombobox.h - QgsFieldListComboBox
|
||||
|
||||
qgsfeaturelistcombobox.h - QgsFeatureListComboBox
|
||||
---------------------
|
||||
begin : 10.3.2017
|
||||
copyright : (C) 2017 by Matthias Kuhn
|
||||
@ -27,6 +26,7 @@ class QgsFeatureFilterModel;
|
||||
class QgsAnimatedIcon;
|
||||
class QgsFilterLineEdit;
|
||||
|
||||
|
||||
/**
|
||||
* \ingroup gui
|
||||
* This offers a combobox with autocompleter that allows selecting features from a layer.
|
||||
@ -44,6 +44,7 @@ class GUI_EXPORT QgsFeatureListComboBox : public QComboBox
|
||||
Q_PROPERTY( QString displayExpression READ displayExpression WRITE setDisplayExpression NOTIFY displayExpressionChanged )
|
||||
Q_PROPERTY( QString filterExpression READ filterExpression WRITE setFilterExpression NOTIFY filterExpressionChanged )
|
||||
Q_PROPERTY( QVariant identifierValue READ identifierValue WRITE setIdentifierValue NOTIFY identifierValueChanged )
|
||||
Q_PROPERTY( QVariantList identifierValues READ identifierValues WRITE setIdentifierValues NOTIFY identifierValueChanged )
|
||||
Q_PROPERTY( QString identifierField READ identifierField WRITE setIdentifierField NOTIFY identifierFieldChanged )
|
||||
Q_PROPERTY( bool allowNull READ allowNull WRITE setAllowNull NOTIFY allowNullChanged )
|
||||
|
||||
@ -64,6 +65,12 @@ class GUI_EXPORT QgsFeatureListComboBox : public QComboBox
|
||||
*/
|
||||
void setSourceLayer( QgsVectorLayer *sourceLayer );
|
||||
|
||||
/**
|
||||
* Sets the current index by using the given feature
|
||||
* \since QGIS 3.10
|
||||
*/
|
||||
void setCurrentFeature( const QgsFeature &feature );
|
||||
|
||||
/**
|
||||
* The display expression will be used to display features as well as
|
||||
* the value to match the typed text against.
|
||||
@ -101,14 +108,31 @@ class GUI_EXPORT QgsFeatureListComboBox : public QComboBox
|
||||
/**
|
||||
* The identifier value of the currently selected feature. A value from the
|
||||
* identifierField.
|
||||
* \deprecated since QGIS 3.10
|
||||
*/
|
||||
QVariant identifierValue() const;
|
||||
Q_DECL_DEPRECATED QVariant identifierValue() const SIP_DEPRECATED;
|
||||
|
||||
/**
|
||||
* The identifier values of the currently selected feature. A value from the
|
||||
* identifierField.
|
||||
* \since QGIS 3.10
|
||||
*/
|
||||
QVariantList identifierValues() const;
|
||||
|
||||
|
||||
/**
|
||||
* The identifier value of the currently selected feature. A value from the
|
||||
* identifierField.
|
||||
* \deprecated since QGIS 3.10 use setIdentifierValues
|
||||
*/
|
||||
void setIdentifierValue( const QVariant &identifierValue );
|
||||
Q_DECL_DEPRECATED void setIdentifierValue( const QVariant &identifierValue ) SIP_DEPRECATED;
|
||||
|
||||
/**
|
||||
* The identifier values of the currently selected feature. A value from the
|
||||
* identifierFields.
|
||||
* \since QGIS 3.10
|
||||
*/
|
||||
void setIdentifierValues( const QVariantList &identifierValues );
|
||||
|
||||
/**
|
||||
* Shorthand for getting a feature request to query the currently selected
|
||||
@ -129,14 +153,30 @@ class GUI_EXPORT QgsFeatureListComboBox : public QComboBox
|
||||
/**
|
||||
* Field name that will be used to uniquely identify the current feature.
|
||||
* Normally the primary key of the layer.
|
||||
* \deprecated since QGIS 3.10
|
||||
*/
|
||||
QString identifierField() const;
|
||||
Q_DECL_DEPRECATED QString identifierField() const SIP_DEPRECATED;
|
||||
|
||||
/**
|
||||
* Field name that will be used to uniquely identify the current feature.
|
||||
* Normally the primary key of the layer.
|
||||
* \since QGIS 3.10
|
||||
*/
|
||||
void setIdentifierField( const QString &identifierField );
|
||||
QStringList identifierFields() const;
|
||||
|
||||
/**
|
||||
* Field name that will be used to uniquely identify the current feature.
|
||||
* Normally the primary key of the layer.
|
||||
* \deprecated since QGIS 3.10
|
||||
*/
|
||||
Q_DECL_DEPRECATED void setIdentifierField( const QString &identifierField ) SIP_DEPRECATED;
|
||||
|
||||
/**
|
||||
* Field name that will be used to uniquely identify the current feature.
|
||||
* Normally the primary key of the layer.
|
||||
* \since QGIS 3.10
|
||||
*/
|
||||
void setIdentifierFields( const QStringList &identifierFields );
|
||||
|
||||
/**
|
||||
* The index of the currently selected item.
|
||||
@ -225,4 +265,6 @@ class GUI_EXPORT QgsFeatureListComboBox : public QComboBox
|
||||
friend class TestQgsFeatureListComboBox;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif // QGSFIELDLISTCOMBOBOX_H
|
||||
|
Loading…
x
Reference in New Issue
Block a user