Skip to content

Commit c661ab1

Browse files
committedOct 26, 2017
Allow using NULL values
1 parent 2a185a0 commit c661ab1

File tree

7 files changed

+101
-25
lines changed

7 files changed

+101
-25
lines changed
 

‎python/core/qgsfeaturefiltermodel.sip

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,17 @@ class QgsFeatureFilterModel : QAbstractItemModel
141141
:rtype: bool
142142
%End
143143

144+
bool allowNull() const;
145+
%Docstring
146+
Add a NULL entry to the list.
147+
:rtype: bool
148+
%End
149+
150+
void setAllowNull( bool allowNull );
151+
%Docstring
152+
Add a NULL entry to the list.
153+
%End
154+
144155
signals:
145156

146157
void sourceLayerChanged();
@@ -211,6 +222,11 @@ class QgsFeatureFilterModel : QAbstractItemModel
211222
Notification that the model change is finished. Will always be emitted in sync with beginUpdate.
212223
%End
213224

225+
void allowNullChanged();
226+
%Docstring
227+
Add a NULL entry to the list.
228+
%End
229+
214230
};
215231

216232
/************************************************************************

‎python/gui/qgsfeaturelistcombobox.sip

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,8 +92,6 @@ class QgsFeatureListComboBox : QComboBox
9292
bool allowNull() const;
9393
%Docstring
9494
Determines if a NULL value should be available in the list.
95-
96-
TODO!
9795
:rtype: bool
9896
%End
9997

‎src/core/qgsfeaturefiltermodel.cpp

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -165,12 +165,18 @@ void QgsFeatureFilterModel::updateCompleter()
165165
}
166166

167167
mShouldReloadCurrentFeature = false;
168+
169+
if ( mFilterValue.isEmpty() )
170+
reload();
168171
}
169172
else
170173
{
171174
// We got strings for a filter selection
172175
std::sort( entries.begin(), entries.end(), []( const Entry & a, const Entry & b ) { return a.value.localeAwareCompare( b.value ) < 0; } );
173176

177+
if ( mAllowNull )
178+
entries.prepend( Entry( QVariant( QVariant::Int ), tr( "NULL" ) ) );
179+
174180
int newEntriesSize = entries.size();
175181

176182
// Find the index of the extra entry in the new list
@@ -196,6 +202,8 @@ void QgsFeatureFilterModel::updateCompleter()
196202

197203
int firstRow = 0;
198204

205+
QgsDebugMsg( QStringLiteral( "Entries 1: %1 " ).arg( mEntries.size() ) );
206+
199207
// Move the extra entry to the first position
200208
if ( mExtraIdentifierValueIndex != -1 )
201209
{
@@ -213,20 +221,26 @@ void QgsFeatureFilterModel::updateCompleter()
213221
firstRow = 1;
214222
}
215223

224+
QgsDebugMsg( QStringLiteral( "Entries 2: %1 " ).arg( mEntries.size() ) );
225+
216226
// Remove all entries (except for extra entry if existent)
217227
beginRemoveRows( QModelIndex(), firstRow, mEntries.size() - firstRow );
218228
mEntries.remove( firstRow, mEntries.size() - firstRow );
219229
endRemoveRows();
220230

231+
QgsDebugMsg( QStringLiteral( "Entries 3: %1 " ).arg( mEntries.size() ) );
232+
221233
if ( currentEntryInNewList == -1 )
222234
{
235+
QgsDebugMsg( QStringLiteral( "Current value is NOT in new list" ) );
223236
beginInsertRows( QModelIndex(), 1, entries.size() + 1 );
224237
mEntries += entries;
225238
endInsertRows();
226239
setExtraIdentifierValueIndex( 0 );
227240
}
228241
else
229242
{
243+
QgsDebugMsg( QStringLiteral( "Current value is in new list" ) );
230244
if ( currentEntryInNewList != 0 )
231245
{
232246
beginInsertRows( QModelIndex(), 0, currentEntryInNewList - 1 );
@@ -335,7 +349,7 @@ void QgsFeatureFilterModel::setExtraIdentifierValueUnguarded( const QVariant &ex
335349
int index = 0;
336350
for ( const Entry &entry : entries )
337351
{
338-
if ( entry.identifierValue == extraIdentifierValue )
352+
if ( entry.identifierValue == extraIdentifierValue && entry.identifierValue.isNull() == extraIdentifierValue.isNull() && entry.identifierValue.isValid() == extraIdentifierValue.isValid() )
339353
{
340354
setExtraIdentifierValueIndex( index );
341355
break;
@@ -348,14 +362,33 @@ void QgsFeatureFilterModel::setExtraIdentifierValueUnguarded( const QVariant &ex
348362
if ( mExtraIdentifierValueIndex != index )
349363
{
350364
beginInsertRows( QModelIndex(), 0, 0 );
351-
mEntries.prepend( Entry( extraIdentifierValue, QStringLiteral( "(%1)" ).arg( extraIdentifierValue.toString() ) ) );
365+
if ( extraIdentifierValue.isNull() )
366+
mEntries.prepend( Entry( QVariant( QVariant::Int ), QStringLiteral( "%1" ).arg( tr( "NULL" ) ) ) );
367+
else
368+
mEntries.prepend( Entry( extraIdentifierValue, QStringLiteral( "(%1)" ).arg( extraIdentifierValue.toString() ) ) );
352369
endInsertRows();
353370
setExtraIdentifierValueIndex( 0 );
354371

355372
reloadCurrentFeature();
356373
}
357374
}
358375

376+
bool QgsFeatureFilterModel::allowNull() const
377+
{
378+
return mAllowNull;
379+
}
380+
381+
void QgsFeatureFilterModel::setAllowNull( bool allowNull )
382+
{
383+
if ( mAllowNull == allowNull )
384+
return;
385+
386+
mAllowNull = allowNull;
387+
emit allowNullChanged();
388+
389+
reload();
390+
}
391+
359392
bool QgsFeatureFilterModel::extraValueDoesNotExist() const
360393
{
361394
return mExtraValueDoesNotExist;
@@ -401,7 +434,7 @@ QVariant QgsFeatureFilterModel::extraIdentifierValue() const
401434

402435
void QgsFeatureFilterModel::setExtraIdentifierValue( const QVariant &extraIdentifierValue )
403436
{
404-
if ( extraIdentifierValue == mExtraIdentifierValue && extraIdentifierValue.isNull() == mExtraIdentifierValue.isNull() )
437+
if ( extraIdentifierValue == mExtraIdentifierValue && extraIdentifierValue.isNull() == mExtraIdentifierValue.isNull() && mExtraIdentifierValue.isValid() )
405438
return;
406439

407440
setExtraIdentifierValueUnguarded( extraIdentifierValue );

‎src/core/qgsfeaturefiltermodel.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ class CORE_EXPORT QgsFeatureFilterModel : public QAbstractItemModel
3737
Q_PROPERTY( QString displayExpression READ displayExpression WRITE setDisplayExpression NOTIFY displayExpressionChanged )
3838
Q_PROPERTY( QString filterValue READ filterValue WRITE setFilterValue NOTIFY filterValueChanged )
3939
Q_PROPERTY( QString filterExpression READ filterExpression WRITE setFilterExpression NOTIFY filterExpressionChanged )
40+
Q_PROPERTY( bool allowNull READ allowNull WRITE setAllowNull NOTIFY allowNullChanged )
4041
Q_PROPERTY( bool isLoading READ isLoading NOTIFY isLoadingChanged )
4142

4243
/**
@@ -167,6 +168,16 @@ class CORE_EXPORT QgsFeatureFilterModel : public QAbstractItemModel
167168
*/
168169
bool extraValueDoesNotExist() const;
169170

171+
/**
172+
* Add a NULL entry to the list.
173+
*/
174+
bool allowNull() const;
175+
176+
/**
177+
* Add a NULL entry to the list.
178+
*/
179+
void setAllowNull( bool allowNull );
180+
170181
signals:
171182

172183
/**
@@ -237,6 +248,11 @@ class CORE_EXPORT QgsFeatureFilterModel : public QAbstractItemModel
237248
*/
238249
void endUpdate();
239250

251+
/**
252+
* Add a NULL entry to the list.
253+
*/
254+
void allowNullChanged();
255+
240256
private slots:
241257
void updateCompleter();
242258
void gathererThreadFinished();
@@ -274,6 +290,7 @@ class CORE_EXPORT QgsFeatureFilterModel : public QAbstractItemModel
274290
QTimer mReloadTimer;
275291
bool mShouldReloadCurrentFeature = false;
276292
bool mExtraValueDoesNotExist = false;
293+
bool mAllowNull = false;
277294

278295
QString mIdentifierField;
279296

‎src/gui/editorwidgets/qgsrelationreferencewidget.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -677,8 +677,7 @@ void QgsRelationReferenceWidget::mapIdentification()
677677

678678
void QgsRelationReferenceWidget::comboReferenceChanged( int index )
679679
{
680-
QgsFeatureId fid = mComboBox->itemData( index, QgsAttributeTableModel::FeatureIdRole ).value<QgsFeatureId>();
681-
mReferencedLayer->getFeatures( QgsFeatureRequest().setFilterFid( fid ) ).nextFeature( mFeature );
680+
mReferencedLayer->getFeatures( mComboBox->currentFeatureRequest() ).nextFeature( mFeature );
682681
highlightFeature( mFeature );
683682
updateAttributeEditorFrame( mFeature );
684683
emit foreignKeyChanged( mFeature.attribute( mReferencedFieldIdx ) );

‎src/gui/qgsfeaturelistcombobox.cpp

Lines changed: 29 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,15 @@ QgsFeatureListComboBox::QgsFeatureListComboBox( QWidget *parent )
3838
connect( mModel, &QgsFeatureFilterModel::filterExpressionChanged, this, &QgsFeatureListComboBox::filterExpressionChanged );
3939
connect( mModel, &QgsFeatureFilterModel::isLoadingChanged, this, &QgsFeatureListComboBox::onLoadingChanged );
4040
connect( mModel, &QgsFeatureFilterModel::filterJobCompleted, this, &QgsFeatureListComboBox::onFilterUpdateCompleted );
41+
connect( mModel, &QgsFeatureFilterModel::allowNullChanged, this, &QgsFeatureListComboBox::allowNullChanged );
4142
connect( mModel, &QgsFeatureFilterModel::extraIdentifierValueChanged, this, &QgsFeatureListComboBox::identifierValueChanged );
4243
connect( mModel, &QgsFeatureFilterModel::extraIdentifierValueIndexChanged, this, &QgsFeatureListComboBox::setCurrentIndex );
4344
connect( mModel, &QgsFeatureFilterModel::identifierFieldChanged, this, &QgsFeatureListComboBox::identifierFieldChanged );
4445
connect( mCompleter, static_cast<void( QCompleter::* )( const QModelIndex & )>( &QCompleter::highlighted ), this, &QgsFeatureListComboBox::onItemSelected );
4546
connect( mCompleter, static_cast<void( QCompleter::* )( const QModelIndex & )>( &QCompleter::activated ), this, &QgsFeatureListComboBox::onActivated );
4647
connect( mModel, &QgsFeatureFilterModel::beginUpdate, this, &QgsFeatureListComboBox::storeLineEditState );
4748
connect( mModel, &QgsFeatureFilterModel::endUpdate, this, &QgsFeatureListComboBox::restoreLineEditState );
49+
connect( mModel, &QgsFeatureFilterModel::dataChanged, this, &QgsFeatureListComboBox::onDataChanged );
4850

4951
connect( this, static_cast<void( QgsFeatureListComboBox::* )( int )>( &QgsFeatureListComboBox::currentIndexChanged ), this, &QgsFeatureListComboBox::onCurrentIndexChanged );
5052

@@ -55,10 +57,7 @@ QgsFeatureListComboBox::QgsFeatureListComboBox( QWidget *parent )
5557

5658
connect( mLineEdit, &QgsFilterLineEdit::textEdited, this, &QgsFeatureListComboBox::onCurrentTextChanged );
5759

58-
connect( mLineEdit, &QgsFilterLineEdit::textChanged, this, []( const QString & text )
59-
{
60-
QgsDebugMsg( QStringLiteral( "Edit text changed to %1" ).arg( text ) );
61-
} );
60+
setToolTip( tr( "Just start typing what you are looking for." ) );
6261
}
6362

6463
QgsVectorLayer *QgsFeatureListComboBox::sourceLayer() const
@@ -83,6 +82,7 @@ void QgsFeatureListComboBox::setDisplayExpression( const QString &expression )
8382

8483
void QgsFeatureListComboBox::onCurrentTextChanged( const QString &text )
8584
{
85+
mIsCurrentlyEdited = true;
8686
mPopupRequested = true;
8787
mModel->setFilterValue( text );
8888
}
@@ -107,6 +107,7 @@ void QgsFeatureListComboBox::onItemSelected( const QModelIndex &index )
107107

108108
void QgsFeatureListComboBox::onCurrentIndexChanged( int i )
109109
{
110+
mIsCurrentlyEdited = false;
110111
QModelIndex modelIndex = mModel->index( i, 0, QModelIndex() );
111112
mModel->setExtraIdentifierValue( mModel->data( modelIndex, QgsFeatureFilterModel::IdentifierValueRole ) );
112113
mLineEdit->setText( mModel->data( modelIndex, QgsFeatureFilterModel::ValueRole ).toString() );
@@ -115,19 +116,33 @@ void QgsFeatureListComboBox::onCurrentIndexChanged( int i )
115116
void QgsFeatureListComboBox::onActivated( QModelIndex modelIndex )
116117
{
117118
setIdentifierValue( mModel->data( modelIndex, QgsFeatureFilterModel::IdentifierValueRole ) );
118-
QgsDebugMsg( QStringLiteral( "Activated index" ) );
119-
QgsDebugMsg( QStringLiteral( "%1 %2" ).arg( QString::number( modelIndex.row() ), mModel->data( modelIndex, QgsFeatureFilterModel::ValueRole ).toString() ) );
120119
mLineEdit->setText( mModel->data( modelIndex, QgsFeatureFilterModel::ValueRole ).toString() );
121120
}
122121

123122
void QgsFeatureListComboBox::storeLineEditState()
124123
{
125-
mLineEditState.store( mLineEdit );
124+
if ( mIsCurrentlyEdited )
125+
mLineEditState.store( mLineEdit );
126126
}
127127

128128
void QgsFeatureListComboBox::restoreLineEditState()
129129
{
130-
mLineEditState.restore( mLineEdit );
130+
if ( mIsCurrentlyEdited )
131+
mLineEditState.restore( mLineEdit );
132+
}
133+
134+
void QgsFeatureListComboBox::onDataChanged( const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles )
135+
{
136+
Q_UNUSED( roles )
137+
if ( !mIsCurrentlyEdited )
138+
{
139+
const int currentIndex = mModel->extraIdentifierValueIndex();
140+
if ( currentIndex >= topLeft.row() && currentIndex <= bottomRight.row() )
141+
{
142+
QModelIndex modelIndex = mModel->index( currentIndex, 0, QModelIndex() );
143+
mLineEdit->setText( mModel->data( modelIndex, QgsFeatureFilterModel::ValueRole ).toString() );
144+
}
145+
}
131146
}
132147

133148
QString QgsFeatureListComboBox::identifierField() const
@@ -163,16 +178,12 @@ void QgsFeatureListComboBox::keyPressEvent( QKeyEvent *event )
163178

164179
bool QgsFeatureListComboBox::allowNull() const
165180
{
166-
return mAllowNull;
181+
return mModel->allowNull();
167182
}
168183

169184
void QgsFeatureListComboBox::setAllowNull( bool allowNull )
170185
{
171-
if ( mAllowNull == allowNull )
172-
return;
173-
174-
mAllowNull = allowNull;
175-
emit allowNullChanged();
186+
mModel->setAllowNull( allowNull );
176187
}
177188

178189
QVariant QgsFeatureListComboBox::identifierValue() const
@@ -187,7 +198,10 @@ void QgsFeatureListComboBox::setIdentifierValue( const QVariant &identifierValue
187198

188199
QgsFeatureRequest QgsFeatureListComboBox::currentFeatureRequest() const
189200
{
190-
return QgsFeatureRequest().setFilterExpression( QStringLiteral( "%1 = %2" ).arg( QgsExpression::quotedColumnRef( mModel->identifierField() ), QgsExpression::quotedValue( mModel->extraIdentifierValue() ) ) );
201+
if ( mModel->extraIdentifierValue().isNull() )
202+
return QgsFeatureRequest().setFilterFids( QgsFeatureIds() ); // NULL: Return a request that's guaranteed to not return anything
203+
else
204+
return QgsFeatureRequest().setFilterExpression( QStringLiteral( "%1 = %2" ).arg( QgsExpression::quotedColumnRef( mModel->identifierField() ), QgsExpression::quotedValue( mModel->extraIdentifierValue() ) ) );
191205
}
192206

193207
QString QgsFeatureListComboBox::filterExpression() const

‎src/gui/qgsfeaturelistcombobox.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ class GUI_EXPORT QgsFeatureListComboBox : public QComboBox
4848
Q_PROPERTY( bool allowNull READ allowNull WRITE setAllowNull NOTIFY allowNullChanged )
4949

5050
public:
51+
5152
/**
5253
* Create a new QgsFeatureListComboBox, optionally specifying a \a parent.
5354
*/
@@ -109,8 +110,6 @@ class GUI_EXPORT QgsFeatureListComboBox : public QComboBox
109110

110111
/**
111112
* Determines if a NULL value should be available in the list.
112-
*
113-
* TODO!
114113
*/
115114
bool allowNull() const;
116115

@@ -185,6 +184,7 @@ class GUI_EXPORT QgsFeatureListComboBox : public QComboBox
185184
void onActivated( QModelIndex index );
186185
void storeLineEditState();
187186
void restoreLineEditState();
187+
void onDataChanged( const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles = QVector<int>() );
188188

189189
private:
190190
struct LineEditState
@@ -202,7 +202,6 @@ class GUI_EXPORT QgsFeatureListComboBox : public QComboBox
202202
QCompleter *mCompleter;
203203
QString mDisplayExpression;
204204
QgsFilterLineEdit *mLineEdit;
205-
bool mAllowNull = true;
206205
bool mPopupRequested = false;
207206
bool mIsCurrentlyEdited = false;
208207
LineEditState mLineEditState;

0 commit comments

Comments
 (0)
Please sign in to comment.