Skip to content

Commit

Permalink
reintroduce reload current feature
Browse files Browse the repository at this point in the history
  • Loading branch information
3nids committed Apr 29, 2020
1 parent 82da0fd commit 01516d7
Show file tree
Hide file tree
Showing 4 changed files with 139 additions and 78 deletions.
5 changes: 5 additions & 0 deletions python/core/auto_generated/qgsfeaturepickermodel.sip.in
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,11 @@ Indicator if the model is currently performing any feature iteration in the back
void filterJobCompleted();
%Docstring
Indicates that a filter job has been completed and new data may be available.
%End

void extraValueDoesNotExistChanged();
%Docstring
Flag indicating that the extraIdentifierValue does not exist in the data.
%End

void beginUpdate();
Expand Down
201 changes: 125 additions & 76 deletions src/core/qgsfeaturepickermodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -211,97 +211,121 @@ void QgsFeaturePickerModel::updateCompleter()
{
setCurrentFeatureUnguarded( FID_NULL );
}
// We got strings for a filter selection
std::sort( entries.begin(), entries.end(), []( const QgsFeatureExpressionValuesGatherer::Entry & a, const QgsFeatureExpressionValuesGatherer::Entry & b ) { return a.value.localeAwareCompare( b.value ) < 0; } );

if ( mAllowNull )
// Only reloading the current entry?
bool reloadCurrentFeatureOnly = mGatherer->data().toBool();
if ( reloadCurrentFeatureOnly )
{
entries.prepend( QgsFeatureExpressionValuesGatherer::nullEntry() );
if ( !entries.isEmpty() )
{
mEntries.replace( mCurrentIndex, entries.at( 0 ) );
emit dataChanged( index( mCurrentIndex, 0, QModelIndex() ), index( mCurrentIndex, 0, QModelIndex() ) );
mShouldReloadCurrentFeature = 0;
setExtraValueDoesNotExist( false );
}
else
{
setExtraValueDoesNotExist( true );
}

mShouldReloadCurrentFeature = 0;

if ( mFilterValue.isEmpty() )
reload();
}
else
{
// We got strings for a filter selection
std::sort( entries.begin(), entries.end(), []( const QgsFeatureExpressionValuesGatherer::Entry & a, const QgsFeatureExpressionValuesGatherer::Entry & b ) { return a.value.localeAwareCompare( b.value ) < 0; } );

const int newEntriesSize = entries.size();
if ( mAllowNull )
{
entries.prepend( QgsFeatureExpressionValuesGatherer::nullEntry() );
}

// fixed entry is either NULL or extra value
const int nbFixedEntry = mAllowNull ? 1 : 0 ;
const int newEntriesSize = entries.size();

// Find the index of the current entry in the new list
int currentEntryInNewList = -1;
if ( mCurrentIndex != -1 && mCurrentIndex < mEntries.count() )
{
for ( int i = 0; i < newEntriesSize; ++i )
// fixed entry is either NULL or extra value
const int nbFixedEntry = ( mExtraValueDoesNotExist ? 1 : 0 ) + ( mAllowNull ? 1 : 0 );

// Find the index of the current entry in the new list
int currentEntryInNewList = -1;
if ( mCurrentIndex != -1 && mCurrentIndex < mEntries.count() )
{
if ( entries.at( i ).feature.id() == mEntries.at( mCurrentIndex ).feature.id() )
for ( int i = 0; i < newEntriesSize; ++i )
{
mEntries.replace( mCurrentIndex, entries.at( i ) );
currentEntryInNewList = i;
break;
if ( entries.at( i ).feature.id() == mEntries.at( mCurrentIndex ).feature.id() )
{
mEntries.replace( mCurrentIndex, entries.at( i ) );
currentEntryInNewList = i;
break;
}
}
}
}

int firstRow = 0;
int firstRow = 0;

// Move current entry to the first position if this is a fixed entry or because
// the entry exists in the new list
if ( mCurrentIndex > -1 && ( mCurrentIndex < nbFixedEntry || currentEntryInNewList != -1 ) )
{
if ( mCurrentIndex != 0 )
// Move current entry to the first position if this is a fixed entry or because
// the entry exists in the new list
if ( mCurrentIndex > -1 && ( mCurrentIndex < nbFixedEntry || currentEntryInNewList != -1 ) )
{
beginMoveRows( QModelIndex(), mCurrentIndex, mCurrentIndex, QModelIndex(), 0 );
mEntries.move( mCurrentIndex, 0 );
endMoveRows();
if ( mCurrentIndex != 0 )
{
beginMoveRows( QModelIndex(), mCurrentIndex, mCurrentIndex, QModelIndex(), 0 );
mEntries.move( mCurrentIndex, 0 );
endMoveRows();
}
firstRow = 1;
}
firstRow = 1;
}

// Remove all entries (except for extra entry if existent)
beginRemoveRows( QModelIndex(), firstRow, mEntries.size() - firstRow );
mEntries.remove( firstRow, mEntries.size() - firstRow );

// if we remove all rows before endRemoveRows, setExtraIdentifierValuesUnguarded will be called
// and a null value will be added to mEntries, so we block setExtraIdentifierValuesUnguarded call
// Remove all entries (except for extra entry if existent)
beginRemoveRows( QModelIndex(), firstRow, mEntries.size() - firstRow );
mEntries.remove( firstRow, mEntries.size() - firstRow );

endRemoveRows();
// if we remove all rows before endRemoveRows, setExtraIdentifierValuesUnguarded will be called
// and a null value will be added to mEntries, so we block setExtraIdentifierValuesUnguarded call

endRemoveRows();

if ( currentEntryInNewList == -1 )
{
beginInsertRows( QModelIndex(), firstRow, entries.size() + 1 );
mEntries += entries;
endInsertRows();

// if all entries have been cleaned (firstRow == 0)
// and there is a value in entries, prefer this value over NULL
// else chose the first one (the previous one)
setCurrentIndex( firstRow == 0 && mAllowNull && !entries.isEmpty() ? 1 : 0, firstRow == 0 );
}
else
{
if ( currentEntryInNewList != 0 )
if ( currentEntryInNewList == -1 )
{
beginInsertRows( QModelIndex(), 0, currentEntryInNewList - 1 );
mEntries = entries.mid( 0, currentEntryInNewList ) + mEntries;
beginInsertRows( QModelIndex(), firstRow, entries.size() + 1 );
mEntries += entries;
endInsertRows();

// if all entries have been cleaned (firstRow == 0)
// and there is a value in entries, prefer this value over NULL
// else chose the first one (the previous one)
setCurrentIndex( firstRow == 0 && mAllowNull && !entries.isEmpty() ? 1 : 0, firstRow == 0 );
}
else
{
mEntries.replace( 0, entries.at( 0 ) );
}
if ( currentEntryInNewList != 0 )
{
beginInsertRows( QModelIndex(), 0, currentEntryInNewList - 1 );
mEntries = entries.mid( 0, currentEntryInNewList ) + mEntries;
endInsertRows();
}
else
{
mEntries.replace( 0, entries.at( 0 ) );
}

// don't notify for a change if it's a fixed entry
if ( currentEntryInNewList >= nbFixedEntry )
{
emit dataChanged( index( currentEntryInNewList, 0, QModelIndex() ), index( currentEntryInNewList, 0, QModelIndex() ) );
// don't notify for a change if it's a fixed entry
if ( currentEntryInNewList >= nbFixedEntry )
{
emit dataChanged( index( currentEntryInNewList, 0, QModelIndex() ), index( currentEntryInNewList, 0, QModelIndex() ) );
}

beginInsertRows( QModelIndex(), currentEntryInNewList + 1, newEntriesSize - currentEntryInNewList - 1 );
mEntries += entries.mid( currentEntryInNewList + 1 );
endInsertRows();
setCurrentIndex( currentEntryInNewList );
}

beginInsertRows( QModelIndex(), currentEntryInNewList + 1, newEntriesSize - currentEntryInNewList - 1 );
mEntries += entries.mid( currentEntryInNewList + 1 );
endInsertRows();
setCurrentIndex( currentEntryInNewList );
emit filterJobCompleted();
}

emit filterJobCompleted();

emit endUpdate();


Expand All @@ -328,20 +352,28 @@ void QgsFeaturePickerModel::scheduledReload()

QgsFeatureRequest request;

QString filterClause;
if ( mFilterValue.isEmpty() && !mFilterExpression.isEmpty() )
filterClause = mFilterExpression;
else if ( mFilterExpression.isEmpty() && !mFilterValue.isEmpty() )
filterClause = QStringLiteral( "(%1) ILIKE '%%2%'" ).arg( mDisplayExpression, mFilterValue );
else if ( !mFilterExpression.isEmpty() && !mFilterValue.isEmpty() )
filterClause = QStringLiteral( "(%1) AND ((%2) ILIKE '%%3%')" ).arg( mFilterExpression, mDisplayExpression, mFilterValue );

if ( !filterClause.isEmpty() )
request.setFilterExpression( filterClause );
if ( mShouldReloadCurrentFeature != 0 )
{
request.setFilterFid( mShouldReloadCurrentFeature );
}
else
{
QString filterClause;
if ( mFilterValue.isEmpty() && !mFilterExpression.isEmpty() )
filterClause = mFilterExpression;
else if ( mFilterExpression.isEmpty() && !mFilterValue.isEmpty() )
filterClause = QStringLiteral( "(%1) ILIKE '%%2%'" ).arg( mDisplayExpression, mFilterValue );
else if ( !mFilterExpression.isEmpty() && !mFilterValue.isEmpty() )
filterClause = QStringLiteral( "(%1) AND ((%2) ILIKE '%%3%')" ).arg( mFilterExpression, mDisplayExpression, mFilterValue );

if ( !filterClause.isEmpty() )
request.setFilterExpression( filterClause );
}

request.setLimit( QgsSettings().value( QStringLiteral( "maxEntriesRelationWidget" ), 100, QgsSettings::Gui ).toInt() );

mGatherer = new QgsFeatureExpressionValuesGatherer( mSourceLayer, mDisplayExpression, request );
mGatherer->setData( mShouldReloadCurrentFeature );
connect( mGatherer, &QgsFeatureExpressionValuesGatherer::finished, this, &QgsFeaturePickerModel::updateCompleter );

mGatherer->start();
Expand Down Expand Up @@ -390,15 +422,32 @@ void QgsFeaturePickerModel::setCurrentFeatureUnguarded( const QgsFeatureId &feat
}

// Value not found in current entries
if ( mCurrentIndex != index && ( mAllowNull || featureId == 0 ) )
if ( mCurrentIndex != index && ( mAllowNull || featureId != 0 ) )
{
beginInsertRows( QModelIndex(), 0, 0 );
mEntries.prepend( QgsFeatureExpressionValuesGatherer::nullEntry() );
if ( featureId != 0 )
{
mShouldReloadCurrentFeature = featureId;
mReloadTimer.start();
}
else
{
mEntries.prepend( QgsFeatureExpressionValuesGatherer::nullEntry() );
}
endInsertRows();
setCurrentIndex( 0, true );
}
}

void QgsFeaturePickerModel::setExtraValueDoesNotExist( bool extraValueDoesNotExist )
{
if ( mExtraValueDoesNotExist == extraValueDoesNotExist )
return;

mExtraValueDoesNotExist = extraValueDoesNotExist;
emit extraValueDoesNotExistChanged();
}

QgsConditionalStyle QgsFeaturePickerModel::featureStyle( const QgsFeature &feature ) const
{
if ( !mSourceLayer )
Expand Down Expand Up @@ -445,7 +494,7 @@ void QgsFeaturePickerModel::setAllowNull( bool allowNull )

QgsFeature QgsFeaturePickerModel::currentFeature() const
{
if ( mCurrentIndex < mEntries.count() )
if ( mCurrentIndex >= 0 && mCurrentIndex < mEntries.count() )
return mEntries.at( mCurrentIndex ).feature;
else
return QgsFeature();
Expand Down
9 changes: 8 additions & 1 deletion src/core/qgsfeaturepickermodel.h
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,11 @@ class CORE_EXPORT QgsFeaturePickerModel : public QAbstractItemModel
*/
void filterJobCompleted();

/**
* Flag indicating that the extraIdentifierValue does not exist in the data.
*/
void extraValueDoesNotExistChanged();

/**
* Notification that the model is about to be changed because a job was completed.
*/
Expand All @@ -212,6 +217,7 @@ class CORE_EXPORT QgsFeaturePickerModel : public QAbstractItemModel
void setCurrentIndex( int index, bool force = false );
void reload();
void setCurrentFeatureUnguarded( const QgsFeatureId &featureId );
void setExtraValueDoesNotExist( bool extraValueDoesNotExist );
QgsConditionalStyle featureStyle( const QgsFeature &feature ) const;

QgsVectorLayer *mSourceLayer = nullptr;
Expand All @@ -224,11 +230,12 @@ class CORE_EXPORT QgsFeaturePickerModel : public QAbstractItemModel
QVector<QgsFeatureExpressionValuesGatherer::Entry> mEntries;
QgsFeatureExpressionValuesGatherer *mGatherer = nullptr;
QTimer mReloadTimer;
QgsFeatureId mShouldReloadCurrentFeature = 0;
bool mExtraValueDoesNotExist = false;
bool mAllowNull = false;

int mCurrentIndex = -1;
bool mIsSettingCurrentFeature = false;

};

#endif // QGSFEATUREPICKERMODEL_H
2 changes: 1 addition & 1 deletion src/gui/qgsfeaturepickerwidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ void QgsFeaturePickerWidget::setLayer( QgsVectorLayer *sourceLayer )
mModel->setSourceLayer( sourceLayer );
}

void QgsFeaturePickerWidget::setCurrentFeature(QgsFeatureId featureId )
void QgsFeaturePickerWidget::setCurrentFeature( QgsFeatureId featureId )
{
mModel->setCurrentFeature( featureId );
}
Expand Down

0 comments on commit 01516d7

Please sign in to comment.