mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-14 00:07:35 -04:00
Allow using NULL values
This commit is contained in:
parent
2a185a0c9b
commit
c661ab1090
@ -141,6 +141,17 @@ class QgsFeatureFilterModel : QAbstractItemModel
|
||||
:rtype: bool
|
||||
%End
|
||||
|
||||
bool allowNull() const;
|
||||
%Docstring
|
||||
Add a NULL entry to the list.
|
||||
:rtype: bool
|
||||
%End
|
||||
|
||||
void setAllowNull( bool allowNull );
|
||||
%Docstring
|
||||
Add a NULL entry to the list.
|
||||
%End
|
||||
|
||||
signals:
|
||||
|
||||
void sourceLayerChanged();
|
||||
@ -211,6 +222,11 @@ class QgsFeatureFilterModel : QAbstractItemModel
|
||||
Notification that the model change is finished. Will always be emitted in sync with beginUpdate.
|
||||
%End
|
||||
|
||||
void allowNullChanged();
|
||||
%Docstring
|
||||
Add a NULL entry to the list.
|
||||
%End
|
||||
|
||||
};
|
||||
|
||||
/************************************************************************
|
||||
|
@ -92,8 +92,6 @@ class QgsFeatureListComboBox : QComboBox
|
||||
bool allowNull() const;
|
||||
%Docstring
|
||||
Determines if a NULL value should be available in the list.
|
||||
|
||||
TODO!
|
||||
:rtype: bool
|
||||
%End
|
||||
|
||||
|
@ -165,12 +165,18 @@ void QgsFeatureFilterModel::updateCompleter()
|
||||
}
|
||||
|
||||
mShouldReloadCurrentFeature = false;
|
||||
|
||||
if ( mFilterValue.isEmpty() )
|
||||
reload();
|
||||
}
|
||||
else
|
||||
{
|
||||
// We got strings for a filter selection
|
||||
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 ), tr( "NULL" ) ) );
|
||||
|
||||
int newEntriesSize = entries.size();
|
||||
|
||||
// Find the index of the extra entry in the new list
|
||||
@ -196,6 +202,8 @@ void QgsFeatureFilterModel::updateCompleter()
|
||||
|
||||
int firstRow = 0;
|
||||
|
||||
QgsDebugMsg( QStringLiteral( "Entries 1: %1 " ).arg( mEntries.size() ) );
|
||||
|
||||
// Move the extra entry to the first position
|
||||
if ( mExtraIdentifierValueIndex != -1 )
|
||||
{
|
||||
@ -213,13 +221,18 @@ void QgsFeatureFilterModel::updateCompleter()
|
||||
firstRow = 1;
|
||||
}
|
||||
|
||||
QgsDebugMsg( QStringLiteral( "Entries 2: %1 " ).arg( mEntries.size() ) );
|
||||
|
||||
// Remove all entries (except for extra entry if existent)
|
||||
beginRemoveRows( QModelIndex(), firstRow, mEntries.size() - firstRow );
|
||||
mEntries.remove( firstRow, mEntries.size() - firstRow );
|
||||
endRemoveRows();
|
||||
|
||||
QgsDebugMsg( QStringLiteral( "Entries 3: %1 " ).arg( mEntries.size() ) );
|
||||
|
||||
if ( currentEntryInNewList == -1 )
|
||||
{
|
||||
QgsDebugMsg( QStringLiteral( "Current value is NOT in new list" ) );
|
||||
beginInsertRows( QModelIndex(), 1, entries.size() + 1 );
|
||||
mEntries += entries;
|
||||
endInsertRows();
|
||||
@ -227,6 +240,7 @@ void QgsFeatureFilterModel::updateCompleter()
|
||||
}
|
||||
else
|
||||
{
|
||||
QgsDebugMsg( QStringLiteral( "Current value is in new list" ) );
|
||||
if ( currentEntryInNewList != 0 )
|
||||
{
|
||||
beginInsertRows( QModelIndex(), 0, currentEntryInNewList - 1 );
|
||||
@ -335,7 +349,7 @@ void QgsFeatureFilterModel::setExtraIdentifierValueUnguarded( const QVariant &ex
|
||||
int index = 0;
|
||||
for ( const Entry &entry : entries )
|
||||
{
|
||||
if ( entry.identifierValue == extraIdentifierValue )
|
||||
if ( entry.identifierValue == extraIdentifierValue && entry.identifierValue.isNull() == extraIdentifierValue.isNull() && entry.identifierValue.isValid() == extraIdentifierValue.isValid() )
|
||||
{
|
||||
setExtraIdentifierValueIndex( index );
|
||||
break;
|
||||
@ -348,7 +362,10 @@ void QgsFeatureFilterModel::setExtraIdentifierValueUnguarded( const QVariant &ex
|
||||
if ( mExtraIdentifierValueIndex != index )
|
||||
{
|
||||
beginInsertRows( QModelIndex(), 0, 0 );
|
||||
mEntries.prepend( Entry( extraIdentifierValue, QStringLiteral( "(%1)" ).arg( extraIdentifierValue.toString() ) ) );
|
||||
if ( extraIdentifierValue.isNull() )
|
||||
mEntries.prepend( Entry( QVariant( QVariant::Int ), QStringLiteral( "%1" ).arg( tr( "NULL" ) ) ) );
|
||||
else
|
||||
mEntries.prepend( Entry( extraIdentifierValue, QStringLiteral( "(%1)" ).arg( extraIdentifierValue.toString() ) ) );
|
||||
endInsertRows();
|
||||
setExtraIdentifierValueIndex( 0 );
|
||||
|
||||
@ -356,6 +373,22 @@ void QgsFeatureFilterModel::setExtraIdentifierValueUnguarded( const QVariant &ex
|
||||
}
|
||||
}
|
||||
|
||||
bool QgsFeatureFilterModel::allowNull() const
|
||||
{
|
||||
return mAllowNull;
|
||||
}
|
||||
|
||||
void QgsFeatureFilterModel::setAllowNull( bool allowNull )
|
||||
{
|
||||
if ( mAllowNull == allowNull )
|
||||
return;
|
||||
|
||||
mAllowNull = allowNull;
|
||||
emit allowNullChanged();
|
||||
|
||||
reload();
|
||||
}
|
||||
|
||||
bool QgsFeatureFilterModel::extraValueDoesNotExist() const
|
||||
{
|
||||
return mExtraValueDoesNotExist;
|
||||
@ -401,7 +434,7 @@ QVariant QgsFeatureFilterModel::extraIdentifierValue() const
|
||||
|
||||
void QgsFeatureFilterModel::setExtraIdentifierValue( const QVariant &extraIdentifierValue )
|
||||
{
|
||||
if ( extraIdentifierValue == mExtraIdentifierValue && extraIdentifierValue.isNull() == mExtraIdentifierValue.isNull() )
|
||||
if ( extraIdentifierValue == mExtraIdentifierValue && extraIdentifierValue.isNull() == mExtraIdentifierValue.isNull() && mExtraIdentifierValue.isValid() )
|
||||
return;
|
||||
|
||||
setExtraIdentifierValueUnguarded( extraIdentifierValue );
|
||||
|
@ -37,6 +37,7 @@ class CORE_EXPORT QgsFeatureFilterModel : public QAbstractItemModel
|
||||
Q_PROPERTY( QString displayExpression READ displayExpression WRITE setDisplayExpression NOTIFY displayExpressionChanged )
|
||||
Q_PROPERTY( QString filterValue READ filterValue WRITE setFilterValue NOTIFY filterValueChanged )
|
||||
Q_PROPERTY( QString filterExpression READ filterExpression WRITE setFilterExpression NOTIFY filterExpressionChanged )
|
||||
Q_PROPERTY( bool allowNull READ allowNull WRITE setAllowNull NOTIFY allowNullChanged )
|
||||
Q_PROPERTY( bool isLoading READ isLoading NOTIFY isLoadingChanged )
|
||||
|
||||
/**
|
||||
@ -167,6 +168,16 @@ class CORE_EXPORT QgsFeatureFilterModel : public QAbstractItemModel
|
||||
*/
|
||||
bool extraValueDoesNotExist() const;
|
||||
|
||||
/**
|
||||
* Add a NULL entry to the list.
|
||||
*/
|
||||
bool allowNull() const;
|
||||
|
||||
/**
|
||||
* Add a NULL entry to the list.
|
||||
*/
|
||||
void setAllowNull( bool allowNull );
|
||||
|
||||
signals:
|
||||
|
||||
/**
|
||||
@ -237,6 +248,11 @@ class CORE_EXPORT QgsFeatureFilterModel : public QAbstractItemModel
|
||||
*/
|
||||
void endUpdate();
|
||||
|
||||
/**
|
||||
* Add a NULL entry to the list.
|
||||
*/
|
||||
void allowNullChanged();
|
||||
|
||||
private slots:
|
||||
void updateCompleter();
|
||||
void gathererThreadFinished();
|
||||
@ -274,6 +290,7 @@ class CORE_EXPORT QgsFeatureFilterModel : public QAbstractItemModel
|
||||
QTimer mReloadTimer;
|
||||
bool mShouldReloadCurrentFeature = false;
|
||||
bool mExtraValueDoesNotExist = false;
|
||||
bool mAllowNull = false;
|
||||
|
||||
QString mIdentifierField;
|
||||
|
||||
|
@ -677,8 +677,7 @@ void QgsRelationReferenceWidget::mapIdentification()
|
||||
|
||||
void QgsRelationReferenceWidget::comboReferenceChanged( int index )
|
||||
{
|
||||
QgsFeatureId fid = mComboBox->itemData( index, QgsAttributeTableModel::FeatureIdRole ).value<QgsFeatureId>();
|
||||
mReferencedLayer->getFeatures( QgsFeatureRequest().setFilterFid( fid ) ).nextFeature( mFeature );
|
||||
mReferencedLayer->getFeatures( mComboBox->currentFeatureRequest() ).nextFeature( mFeature );
|
||||
highlightFeature( mFeature );
|
||||
updateAttributeEditorFrame( mFeature );
|
||||
emit foreignKeyChanged( mFeature.attribute( mReferencedFieldIdx ) );
|
||||
|
@ -38,6 +38,7 @@ QgsFeatureListComboBox::QgsFeatureListComboBox( QWidget *parent )
|
||||
connect( mModel, &QgsFeatureFilterModel::filterExpressionChanged, this, &QgsFeatureListComboBox::filterExpressionChanged );
|
||||
connect( mModel, &QgsFeatureFilterModel::isLoadingChanged, this, &QgsFeatureListComboBox::onLoadingChanged );
|
||||
connect( mModel, &QgsFeatureFilterModel::filterJobCompleted, this, &QgsFeatureListComboBox::onFilterUpdateCompleted );
|
||||
connect( mModel, &QgsFeatureFilterModel::allowNullChanged, this, &QgsFeatureListComboBox::allowNullChanged );
|
||||
connect( mModel, &QgsFeatureFilterModel::extraIdentifierValueChanged, this, &QgsFeatureListComboBox::identifierValueChanged );
|
||||
connect( mModel, &QgsFeatureFilterModel::extraIdentifierValueIndexChanged, this, &QgsFeatureListComboBox::setCurrentIndex );
|
||||
connect( mModel, &QgsFeatureFilterModel::identifierFieldChanged, this, &QgsFeatureListComboBox::identifierFieldChanged );
|
||||
@ -45,6 +46,7 @@ QgsFeatureListComboBox::QgsFeatureListComboBox( QWidget *parent )
|
||||
connect( mCompleter, static_cast<void( QCompleter::* )( const QModelIndex & )>( &QCompleter::activated ), this, &QgsFeatureListComboBox::onActivated );
|
||||
connect( mModel, &QgsFeatureFilterModel::beginUpdate, this, &QgsFeatureListComboBox::storeLineEditState );
|
||||
connect( mModel, &QgsFeatureFilterModel::endUpdate, this, &QgsFeatureListComboBox::restoreLineEditState );
|
||||
connect( mModel, &QgsFeatureFilterModel::dataChanged, this, &QgsFeatureListComboBox::onDataChanged );
|
||||
|
||||
connect( this, static_cast<void( QgsFeatureListComboBox::* )( int )>( &QgsFeatureListComboBox::currentIndexChanged ), this, &QgsFeatureListComboBox::onCurrentIndexChanged );
|
||||
|
||||
@ -55,10 +57,7 @@ QgsFeatureListComboBox::QgsFeatureListComboBox( QWidget *parent )
|
||||
|
||||
connect( mLineEdit, &QgsFilterLineEdit::textEdited, this, &QgsFeatureListComboBox::onCurrentTextChanged );
|
||||
|
||||
connect( mLineEdit, &QgsFilterLineEdit::textChanged, this, []( const QString & text )
|
||||
{
|
||||
QgsDebugMsg( QStringLiteral( "Edit text changed to %1" ).arg( text ) );
|
||||
} );
|
||||
setToolTip( tr( "Just start typing what you are looking for." ) );
|
||||
}
|
||||
|
||||
QgsVectorLayer *QgsFeatureListComboBox::sourceLayer() const
|
||||
@ -83,6 +82,7 @@ void QgsFeatureListComboBox::setDisplayExpression( const QString &expression )
|
||||
|
||||
void QgsFeatureListComboBox::onCurrentTextChanged( const QString &text )
|
||||
{
|
||||
mIsCurrentlyEdited = true;
|
||||
mPopupRequested = true;
|
||||
mModel->setFilterValue( text );
|
||||
}
|
||||
@ -107,6 +107,7 @@ void QgsFeatureListComboBox::onItemSelected( const QModelIndex &index )
|
||||
|
||||
void QgsFeatureListComboBox::onCurrentIndexChanged( int i )
|
||||
{
|
||||
mIsCurrentlyEdited = false;
|
||||
QModelIndex modelIndex = mModel->index( i, 0, QModelIndex() );
|
||||
mModel->setExtraIdentifierValue( mModel->data( modelIndex, QgsFeatureFilterModel::IdentifierValueRole ) );
|
||||
mLineEdit->setText( mModel->data( modelIndex, QgsFeatureFilterModel::ValueRole ).toString() );
|
||||
@ -115,19 +116,33 @@ void QgsFeatureListComboBox::onCurrentIndexChanged( int i )
|
||||
void QgsFeatureListComboBox::onActivated( QModelIndex modelIndex )
|
||||
{
|
||||
setIdentifierValue( mModel->data( modelIndex, QgsFeatureFilterModel::IdentifierValueRole ) );
|
||||
QgsDebugMsg( QStringLiteral( "Activated index" ) );
|
||||
QgsDebugMsg( QStringLiteral( "%1 %2" ).arg( QString::number( modelIndex.row() ), mModel->data( modelIndex, QgsFeatureFilterModel::ValueRole ).toString() ) );
|
||||
mLineEdit->setText( mModel->data( modelIndex, QgsFeatureFilterModel::ValueRole ).toString() );
|
||||
}
|
||||
|
||||
void QgsFeatureListComboBox::storeLineEditState()
|
||||
{
|
||||
mLineEditState.store( mLineEdit );
|
||||
if ( mIsCurrentlyEdited )
|
||||
mLineEditState.store( mLineEdit );
|
||||
}
|
||||
|
||||
void QgsFeatureListComboBox::restoreLineEditState()
|
||||
{
|
||||
mLineEditState.restore( mLineEdit );
|
||||
if ( mIsCurrentlyEdited )
|
||||
mLineEditState.restore( mLineEdit );
|
||||
}
|
||||
|
||||
void QgsFeatureListComboBox::onDataChanged( const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles )
|
||||
{
|
||||
Q_UNUSED( roles )
|
||||
if ( !mIsCurrentlyEdited )
|
||||
{
|
||||
const int currentIndex = mModel->extraIdentifierValueIndex();
|
||||
if ( currentIndex >= topLeft.row() && currentIndex <= bottomRight.row() )
|
||||
{
|
||||
QModelIndex modelIndex = mModel->index( currentIndex, 0, QModelIndex() );
|
||||
mLineEdit->setText( mModel->data( modelIndex, QgsFeatureFilterModel::ValueRole ).toString() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QString QgsFeatureListComboBox::identifierField() const
|
||||
@ -163,16 +178,12 @@ void QgsFeatureListComboBox::keyPressEvent( QKeyEvent *event )
|
||||
|
||||
bool QgsFeatureListComboBox::allowNull() const
|
||||
{
|
||||
return mAllowNull;
|
||||
return mModel->allowNull();
|
||||
}
|
||||
|
||||
void QgsFeatureListComboBox::setAllowNull( bool allowNull )
|
||||
{
|
||||
if ( mAllowNull == allowNull )
|
||||
return;
|
||||
|
||||
mAllowNull = allowNull;
|
||||
emit allowNullChanged();
|
||||
mModel->setAllowNull( allowNull );
|
||||
}
|
||||
|
||||
QVariant QgsFeatureListComboBox::identifierValue() const
|
||||
@ -187,7 +198,10 @@ void QgsFeatureListComboBox::setIdentifierValue( const QVariant &identifierValue
|
||||
|
||||
QgsFeatureRequest QgsFeatureListComboBox::currentFeatureRequest() const
|
||||
{
|
||||
return QgsFeatureRequest().setFilterExpression( QStringLiteral( "%1 = %2" ).arg( QgsExpression::quotedColumnRef( mModel->identifierField() ), QgsExpression::quotedValue( mModel->extraIdentifierValue() ) ) );
|
||||
if ( mModel->extraIdentifierValue().isNull() )
|
||||
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() ) ) );
|
||||
}
|
||||
|
||||
QString QgsFeatureListComboBox::filterExpression() const
|
||||
|
@ -48,6 +48,7 @@ class GUI_EXPORT QgsFeatureListComboBox : public QComboBox
|
||||
Q_PROPERTY( bool allowNull READ allowNull WRITE setAllowNull NOTIFY allowNullChanged )
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Create a new QgsFeatureListComboBox, optionally specifying a \a parent.
|
||||
*/
|
||||
@ -109,8 +110,6 @@ class GUI_EXPORT QgsFeatureListComboBox : public QComboBox
|
||||
|
||||
/**
|
||||
* Determines if a NULL value should be available in the list.
|
||||
*
|
||||
* TODO!
|
||||
*/
|
||||
bool allowNull() const;
|
||||
|
||||
@ -185,6 +184,7 @@ class GUI_EXPORT QgsFeatureListComboBox : public QComboBox
|
||||
void onActivated( QModelIndex index );
|
||||
void storeLineEditState();
|
||||
void restoreLineEditState();
|
||||
void onDataChanged( const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles = QVector<int>() );
|
||||
|
||||
private:
|
||||
struct LineEditState
|
||||
@ -202,7 +202,6 @@ class GUI_EXPORT QgsFeatureListComboBox : public QComboBox
|
||||
QCompleter *mCompleter;
|
||||
QString mDisplayExpression;
|
||||
QgsFilterLineEdit *mLineEdit;
|
||||
bool mAllowNull = true;
|
||||
bool mPopupRequested = false;
|
||||
bool mIsCurrentlyEdited = false;
|
||||
LineEditState mLineEditState;
|
||||
|
Loading…
x
Reference in New Issue
Block a user