QGIS API Documentation  3.10.0-A Coruña (6c816b4204)
qgsfeaturefiltermodel.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsfeaturefiltermodel.cpp - QgsFeatureFilterModel
3  ---------------------
4  begin : 10.3.2017
5  copyright : (C) 2017 by Matthias Kuhn
6  email : [email protected]
7  ***************************************************************************
8  * *
9  * This program is free software; you can redistribute it and/or modify *
10  * it under the terms of the GNU General Public License as published by *
11  * the Free Software Foundation; either version 2 of the License, or *
12  * (at your option) any later version. *
13  * *
14  ***************************************************************************/
15 #include "qgsfeaturefiltermodel.h"
17 
18 #include "qgsvectorlayer.h"
19 #include "qgsconditionalstyle.h"
20 #include "qgsapplication.h"
21 #include "qgssettings.h"
22 
23 
24 bool qVariantListCompare( const QVariantList &a, const QVariantList &b )
25 {
26  if ( a.size() != b.size() )
27  return false;
28 
29  for ( int i = 0; i < a.size(); ++i )
30  {
31  if ( !qgsVariantEqual( a.at( i ), b.at( i ) ) )
32  return false;
33  }
34  return true;
35 }
36 
38  : QAbstractItemModel( parent )
39 {
40  mReloadTimer.setInterval( 100 );
41  mReloadTimer.setSingleShot( true );
42  connect( &mReloadTimer, &QTimer::timeout, this, &QgsFeatureFilterModel::scheduledReload );
43  setExtraIdentifierValuesUnguarded( QVariantList() );
44 }
45 
47 {
48  if ( mGatherer )
49  connect( mGatherer, &QgsFieldExpressionValuesGatherer::finished, mGatherer, &QgsFieldExpressionValuesGatherer::deleteLater );
50 }
51 
53 {
54  return mSourceLayer;
55 }
56 
58 {
59  if ( mSourceLayer == sourceLayer )
60  return;
61 
62  mSourceLayer = sourceLayer;
63  mExpressionContext = sourceLayer->createExpressionContext();
64  reload();
65  emit sourceLayerChanged();
66 }
67 
69 {
70  return mDisplayExpression.expression();
71 }
72 
74 {
75  if ( mDisplayExpression.expression() == displayExpression )
76  return;
77 
78  mDisplayExpression = QgsExpression( displayExpression );
79  reload();
81 }
82 
84 {
85  return mFilterValue;
86 }
87 
89 {
90  if ( mFilterValue == filterValue )
91  return;
92 
93  mFilterValue = filterValue;
94  reload();
95  emit filterValueChanged();
96 }
97 
99 {
100  return mFilterExpression;
101 }
102 
104 {
105  if ( mFilterExpression == filterExpression )
106  return;
107 
108  mFilterExpression = filterExpression;
109  reload();
111 }
112 
114 {
115  return mGatherer;
116 }
117 
119 {
120  return mIdentifierFields.value( 0 );
121 }
122 
123 QModelIndex QgsFeatureFilterModel::index( int row, int column, const QModelIndex &parent ) const
124 {
125  Q_UNUSED( parent )
126  return createIndex( row, column, nullptr );
127 }
128 
129 QModelIndex QgsFeatureFilterModel::parent( const QModelIndex &child ) const
130 {
131  Q_UNUSED( child )
132  return QModelIndex();
133 }
134 
135 int QgsFeatureFilterModel::rowCount( const QModelIndex &parent ) const
136 {
137  Q_UNUSED( parent )
138 
139  return mEntries.size();
140 }
141 
142 int QgsFeatureFilterModel::columnCount( const QModelIndex &parent ) const
143 {
144  Q_UNUSED( parent )
145  return 1;
146 }
147 
148 QVariant QgsFeatureFilterModel::data( const QModelIndex &index, int role ) const
149 {
150  if ( !index.isValid() )
151  return QVariant();
152 
153  switch ( role )
154  {
155  case Qt::DisplayRole:
156  case Qt::EditRole:
157  case ValueRole:
158  return mEntries.value( index.row() ).value;
159 
160  case IdentifierValueRole:
161  {
162  const QVariantList values = mEntries.value( index.row() ).identifierValues;
163  return values.value( 0 );
164  }
165 
167  return mEntries.value( index.row() ).identifierValues;
168 
169  case Qt::BackgroundColorRole:
170  case Qt::TextColorRole:
171  case Qt::DecorationRole:
172  case Qt::FontRole:
173  {
174  bool isNull = true;
175  const QVariantList values = mEntries.value( index.row() ).identifierValues;
176  for ( const QVariant &value : values )
177  {
178  if ( !value.isNull() )
179  {
180  isNull = false;
181  break;
182  }
183  }
184  if ( isNull )
185  {
186  // Representation for NULL value
187  if ( role == Qt::TextColorRole )
188  {
189  return QBrush( QColor( Qt::gray ) );
190  }
191  if ( role == Qt::FontRole )
192  {
193  QFont font = QFont();
194  if ( index.row() == mExtraIdentifierValueIndex )
195  font.setBold( true );
196  else
197  font.setItalic( true );
198  return font;
199  }
200  }
201  else
202  {
203  // Respect conditional style
204  const QgsConditionalStyle style = featureStyle( mEntries.value( index.row() ).feature );
205 
206  if ( style.isValid() )
207  {
208  if ( role == Qt::BackgroundColorRole && style.validBackgroundColor() )
209  return style.backgroundColor();
210  if ( role == Qt::TextColorRole && style.validTextColor() )
211  return style.textColor();
212  if ( role == Qt::DecorationRole )
213  return style.icon();
214  if ( role == Qt::FontRole )
215  return style.font();
216  }
217  }
218  break;
219  }
220  }
221 
222  return QVariant();
223 }
224 
225 void QgsFeatureFilterModel::updateCompleter()
226 {
227  emit beginUpdate();
228  QVector<Entry> entries = mGatherer->entries();
229 
230  if ( mExtraIdentifierValueIndex == -1 )
231  {
232  setExtraIdentifierValuesUnguarded( QVariantList() );
233  }
234 
235  // Only reloading the current entry?
236  if ( mGatherer->data().toBool() )
237  {
238  if ( !entries.isEmpty() )
239  {
240  mEntries.replace( mExtraIdentifierValueIndex, entries.at( 0 ) );
241  emit dataChanged( index( mExtraIdentifierValueIndex, 0, QModelIndex() ), index( mExtraIdentifierValueIndex, 0, QModelIndex() ) );
242  mShouldReloadCurrentFeature = false;
243  setExtraValueDoesNotExist( false );
244  }
245  else
246  {
247  setExtraValueDoesNotExist( true );
248  }
249 
250  mShouldReloadCurrentFeature = false;
251 
252  if ( mFilterValue.isEmpty() )
253  reload();
254  }
255  else
256  {
257  // We got strings for a filter selection
258  std::sort( entries.begin(), entries.end(), []( const Entry & a, const Entry & b ) { return a.value.localeAwareCompare( b.value ) < 0; } );
259 
260  if ( mAllowNull )
261  {
262  entries.prepend( nullEntry() );
263  }
264 
265  const int newEntriesSize = entries.size();
266 
267  // Find the index of the extra entry in the new list
268  int currentEntryInNewList = -1;
269  if ( mExtraIdentifierValueIndex != -1 )
270  {
271  for ( int i = 0; i < newEntriesSize; ++i )
272  {
273  if ( qVariantListCompare( entries.at( i ).identifierValues, mExtraIdentifierValues ) )
274  {
275  currentEntryInNewList = i;
276  mEntries.replace( mExtraIdentifierValueIndex, entries.at( i ) );
277  emit dataChanged( index( mExtraIdentifierValueIndex, 0, QModelIndex() ), index( mExtraIdentifierValueIndex, 0, QModelIndex() ) );
278  setExtraValueDoesNotExist( false );
279  break;
280  }
281  }
282  }
283  else
284  {
285  Q_ASSERT_X( false, "QgsFeatureFilterModel::updateCompleter", "No extra identifier value generated. Should not get here." );
286  }
287 
288  int firstRow = 0;
289 
290  // Move the extra entry to the first position
291  if ( mExtraIdentifierValueIndex != -1 )
292  {
293  if ( mExtraIdentifierValueIndex != 0 )
294  {
295  beginMoveRows( QModelIndex(), mExtraIdentifierValueIndex, mExtraIdentifierValueIndex, QModelIndex(), 0 );
296  mEntries.move( mExtraIdentifierValueIndex, 0 );
297  endMoveRows();
298  }
299  firstRow = 1;
300  }
301 
302  // Remove all entries (except for extra entry if existent)
303  beginRemoveRows( QModelIndex(), firstRow, mEntries.size() - firstRow );
304  mEntries.remove( firstRow, mEntries.size() - firstRow );
305  endRemoveRows();
306 
307  if ( currentEntryInNewList == -1 )
308  {
309  beginInsertRows( QModelIndex(), 1, entries.size() + 1 );
310  mEntries += entries;
311  endInsertRows();
312  setExtraIdentifierValuesIndex( 0 );
313  }
314  else
315  {
316  if ( currentEntryInNewList != 0 )
317  {
318  beginInsertRows( QModelIndex(), 0, currentEntryInNewList - 1 );
319  mEntries = entries.mid( 0, currentEntryInNewList ) + mEntries;
320  endInsertRows();
321  }
322  else
323  {
324  mEntries.replace( 0, entries.at( 0 ) );
325  }
326 
327  emit dataChanged( index( currentEntryInNewList, 0, QModelIndex() ), index( currentEntryInNewList, 0, QModelIndex() ) );
328 
329  beginInsertRows( QModelIndex(), currentEntryInNewList + 1, newEntriesSize - currentEntryInNewList - 1 );
330  mEntries += entries.mid( currentEntryInNewList + 1 );
331  endInsertRows();
332  setExtraIdentifierValuesIndex( currentEntryInNewList );
333  }
334 
335  emit filterJobCompleted();
336  }
337  emit endUpdate();
338 }
339 
340 void QgsFeatureFilterModel::gathererThreadFinished()
341 {
342  delete mGatherer;
343  mGatherer = nullptr;
344  emit isLoadingChanged();
345 }
346 
347 void QgsFeatureFilterModel::scheduledReload()
348 {
349  if ( !mSourceLayer )
350  return;
351 
352  bool wasLoading = false;
353 
354  if ( mGatherer )
355  {
356  // Send the gatherer thread to the graveyard:
357  // forget about it, tell it to stop and delete when finished
358  disconnect( mGatherer, &QgsFieldExpressionValuesGatherer::collectedValues, this, &QgsFeatureFilterModel::updateCompleter );
359  disconnect( mGatherer, &QgsFieldExpressionValuesGatherer::finished, this, &QgsFeatureFilterModel::gathererThreadFinished );
360  connect( mGatherer, &QgsFieldExpressionValuesGatherer::finished, mGatherer, &QgsFieldExpressionValuesGatherer::deleteLater );
361  mGatherer->stop();
362  wasLoading = true;
363  }
364 
365  QgsFeatureRequest request;
366 
367  if ( mShouldReloadCurrentFeature )
368  {
369  QStringList conditions;
370  for ( int i = 0; i < mIdentifierFields.count(); i++ )
371  {
372  if ( i >= mExtraIdentifierValues.count() )
373  {
374  conditions << QgsExpression::createFieldEqualityExpression( mIdentifierFields.at( i ), QVariant() );
375  }
376  else
377  {
378  conditions << QgsExpression::createFieldEqualityExpression( mIdentifierFields.at( i ), mExtraIdentifierValues.at( i ) );
379  }
380  }
381  request.setFilterExpression( conditions.join( QStringLiteral( " AND " ) ) );
382  }
383  else
384  {
385  QString filterClause;
386 
387  if ( mFilterValue.isEmpty() && !mFilterExpression.isEmpty() )
388  filterClause = mFilterExpression;
389  else if ( mFilterExpression.isEmpty() && !mFilterValue.isEmpty() )
390  filterClause = QStringLiteral( "(%1) ILIKE '%%2%'" ).arg( mDisplayExpression, mFilterValue );
391  else if ( !mFilterExpression.isEmpty() && !mFilterValue.isEmpty() )
392  filterClause = QStringLiteral( "(%1) AND ((%2) ILIKE '%%3%')" ).arg( mFilterExpression, mDisplayExpression, mFilterValue );
393 
394  if ( !filterClause.isEmpty() )
395  request.setFilterExpression( filterClause );
396  }
397  QSet<QString> attributes;
398  if ( request.filterExpression() )
399  attributes = request.filterExpression()->referencedColumns();
400  for ( const QString &fieldName : qgis::as_const( mIdentifierFields ) )
401  attributes << fieldName;
402  request.setSubsetOfAttributes( attributes, mSourceLayer->fields() );
404 
405  request.setLimit( QgsSettings().value( QStringLiteral( "maxEntriesRelationWidget" ), 100, QgsSettings::Gui ).toInt() );
406 
407  mGatherer = new QgsFieldExpressionValuesGatherer( mSourceLayer, mDisplayExpression, mIdentifierFields, request );
408  mGatherer->setData( mShouldReloadCurrentFeature );
409 
410  connect( mGatherer, &QgsFieldExpressionValuesGatherer::collectedValues, this, &QgsFeatureFilterModel::updateCompleter );
411  connect( mGatherer, &QgsFieldExpressionValuesGatherer::finished, this, &QgsFeatureFilterModel::gathererThreadFinished );
412 
413  mGatherer->start();
414  if ( !wasLoading )
415  emit isLoadingChanged();
416 }
417 
418 QSet<QString> QgsFeatureFilterModel::requestedAttributes() const
419 {
420  QSet<QString> requestedAttrs;
421 
422  const auto rowStyles = mSourceLayer->conditionalStyles()->rowStyles();
423 
424  for ( const QgsConditionalStyle &style : rowStyles )
425  {
426  QgsExpression exp( style.rule() );
427  requestedAttrs += exp.referencedColumns();
428  }
429 
430  if ( mDisplayExpression.isField() )
431  {
432  QString fieldName = *mDisplayExpression.referencedColumns().constBegin();
433  const auto constFieldStyles = mSourceLayer->conditionalStyles()->fieldStyles( fieldName );
434  for ( const QgsConditionalStyle &style : constFieldStyles )
435  {
436  QgsExpression exp( style.rule() );
437  requestedAttrs += exp.referencedColumns();
438  }
439  }
440 
441  return requestedAttrs;
442 }
443 
444 void QgsFeatureFilterModel::setExtraIdentifierValuesIndex( int index, bool force )
445 {
446  if ( mExtraIdentifierValueIndex == index && !force )
447  return;
448 
449  mExtraIdentifierValueIndex = index;
451 }
452 
453 void QgsFeatureFilterModel::reloadCurrentFeature()
454 {
455  mShouldReloadCurrentFeature = true;
456  mReloadTimer.start();
457 }
458 
459 void QgsFeatureFilterModel::setExtraIdentifierValuesUnguarded( const QVariantList &extraIdentifierValues )
460 {
461  const QVector<Entry> entries = mEntries;
462 
463  int index = 0;
464  for ( const Entry &entry : entries )
465  {
466  if ( entry.identifierValues == extraIdentifierValues )
467  {
468  setExtraIdentifierValuesIndex( index );
469  break;
470  }
471 
472  index++;
473  }
474 
475  // Value not found in current entries
476  if ( mExtraIdentifierValueIndex != index )
477  {
478  beginInsertRows( QModelIndex(), 0, 0 );
479  if ( extraIdentifierValues.isEmpty() )
480  {
481  mEntries.prepend( nullEntry() );
482  }
483  else
484  {
485  QStringList values;
486  for ( const QVariant &v : qgis::as_const( extraIdentifierValues ) )
487  values << QStringLiteral( "(%1)" ).arg( v.toString() );
488 
489  mEntries.prepend( Entry( extraIdentifierValues, values.join( QStringLiteral( " " ) ), QgsFeature() ) );
490  }
491  endInsertRows();
492 
493  setExtraIdentifierValuesIndex( 0, true );
494 
495  reloadCurrentFeature();
496  }
497 }
498 
499 QgsFeatureFilterModel::Entry QgsFeatureFilterModel::nullEntry()
500 {
501  return Entry( QVariantList(), QgsApplication::nullRepresentation(), QgsFeature() );
502 }
503 
504 QgsConditionalStyle QgsFeatureFilterModel::featureStyle( const QgsFeature &feature ) const
505 {
506  if ( !mSourceLayer )
507  return QgsConditionalStyle();
508 
509  QgsVectorLayer *layer = mSourceLayer;
510  QgsFeatureId fid = feature.id();
511  mExpressionContext.setFeature( feature );
512 
513  auto styles = QgsConditionalStyle::matchingConditionalStyles( layer->conditionalStyles()->rowStyles(), QVariant(), mExpressionContext );
514 
515  if ( mDisplayExpression.referencedColumns().count() == 1 )
516  {
517  // Style specific for this field
518  QString fieldName = *mDisplayExpression.referencedColumns().constBegin();
519  const auto allStyles = layer->conditionalStyles()->fieldStyles( fieldName );
520  const auto matchingFieldStyles = QgsConditionalStyle::matchingConditionalStyles( allStyles, feature.attribute( fieldName ), mExpressionContext );
521 
522  styles += matchingFieldStyles;
523  }
524 
525  QgsConditionalStyle style;
526  style = QgsConditionalStyle::compressStyles( styles );
527  mEntryStylesMap.insert( fid, style );
528 
529  return style;
530 }
531 
533 {
534  return mAllowNull;
535 }
536 
538 {
539  if ( mAllowNull == allowNull )
540  return;
541 
542  mAllowNull = allowNull;
543  emit allowNullChanged();
544 
545  reload();
546 }
547 
549 {
550  return mExtraValueDoesNotExist;
551 }
552 
553 void QgsFeatureFilterModel::setExtraValueDoesNotExist( bool extraValueDoesNotExist )
554 {
555  if ( mExtraValueDoesNotExist == extraValueDoesNotExist )
556  return;
557 
558  mExtraValueDoesNotExist = extraValueDoesNotExist;
560 }
561 
563 {
564  return mExtraIdentifierValueIndex;
565 }
566 
568 {
569  return mIdentifierFields;
570 }
571 
573 {
574  setIdentifierFields( QStringList() << identifierField );
575 }
576 
578 {
579  if ( mIdentifierFields == identifierFields )
580  return;
581 
582  mIdentifierFields = identifierFields;
583  emit identifierFieldChanged();
584  setExtraIdentifierValues( QVariantList() );
585 }
586 
587 void QgsFeatureFilterModel::reload()
588 {
589  mReloadTimer.start();
590 }
591 
593 {
594  if ( mExtraIdentifierValues.isEmpty() )
595  return QVariant();
596  else
597  return mExtraIdentifierValues.at( 0 );
598 }
599 
601 {
602  if ( mExtraIdentifierValues.count() != mIdentifierFields.count() )
603  {
604  QVariantList nullValues;
605  for ( int i = 0; i < mIdentifierFields.count(); i++ )
606  nullValues << QVariant();
607  return nullValues;
608  }
609  return mExtraIdentifierValues;
610 }
611 
613 {
614  if ( extraIdentifierValue.isNull() )
615  setExtraIdentifierValues( QVariantList() );
616  else
617  setExtraIdentifierValues( QVariantList() << extraIdentifierValue );
618 }
619 
621 {
622  if ( extraIdentifierValues == mExtraIdentifierValues && !mExtraIdentifierValues.isEmpty() )
623  return;
624 
625  if ( mIsSettingExtraIdentifierValue )
626  return;
627 
628  mIsSettingExtraIdentifierValue = true;
629 
630  mExtraIdentifierValues = extraIdentifierValues;
631 
632  setExtraIdentifierValuesUnguarded( extraIdentifierValues );
633 
634  mIsSettingExtraIdentifierValue = false;
635 
637 }
638 
640 {
641  mExtraIdentifierValues = QVariantList();
642 }
Class for parsing and evaluation of expressions (formerly called "search strings").
void filterValueChanged()
This value will be used to filter the features available from this model.
QgsFeatureId id
Definition: qgsfeature.h:64
void setExtraIdentifierValues(const QVariantList &extraIdentifierValues)
Allows specifying one value that does not need to match the filter criteria but will still be availab...
bool allowNull() const
Add a NULL entry to the list.
void beginUpdate()
Notification that the model is about to be changed because a job was completed.
QStringList identifierFields() const
The identifier field should be a unique field that can be used to identify individual features...
This class is a composition of two QSettings instances:
Definition: qgssettings.h:58
int rowCount(const QModelIndex &parent) const override
Used to retrieve the displayExpression of a feature.
void setFeature(const QgsFeature &feature)
Convenience function for setting a feature for the context.
void setFilterExpression(const QString &filterExpression)
An additional filter expression to apply, next to the filterValue.
QString filterValue() const
This value will be used to filter the features available from this model.
QVariantList extraIdentifierValues() const
Allows specifying one value that does not need to match the filter criteria but will still be availab...
qint64 QgsFeatureId
Definition: qgsfeatureid.h:25
QgsFeatureRequest & setSubsetOfAttributes(const QgsAttributeList &attrs)
Set a subset of attributes that will be fetched.
void filterJobCompleted()
Indicates that a filter job has been completed and new data may be available.
bool validBackgroundColor() const
Check if the background color is valid for render.
QPixmap icon() const
The icon set for style generated from the set symbol.
void setExtraIdentifierValuesToNull()
Allows specifying one value that does not need to match the filter criteria but will still be availab...
bool extraValueDoesNotExist() const
Flag indicating that the extraIdentifierValue does not exist in the data.
void extraIdentifierValueIndexChanged(int index)
The index at which the extra identifier value is available within the model.
QSet< QString > referencedColumns() const
Gets list of columns referenced by the expression.
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:55
friend class QgsFieldExpressionValuesGatherer
QgsConditionalLayerStyles * conditionalStyles() const
Returns the conditional styles that are set for this layer.
QgsExpression * filterExpression() const
Returns the filter expression if set.
int extraIdentifierValueIndex() const
The index at which the extra identifier value is available within the model.
Q_DECL_DEPRECATED QVariant extraIdentifierValue() const
Allows specifying one value that does not need to match the filter criteria but will still be availab...
QgsFeatureRequest & setFilterExpression(const QString &expression)
Set the filter expression.
void identifierFieldChanged()
The identifier field should be a unique field that can be used to identify individual features...
QgsFields fields() const FINAL
Returns the list of fields of this layer.
Conditional styling for a rule.
QString displayExpression() const
The display expression will be used for.
bool isValid() const
isValid Check if this rule is valid.
static QList< QgsConditionalStyle > matchingConditionalStyles(const QList< QgsConditionalStyle > &styles, const QVariant &value, QgsExpressionContext &context)
Find and return the matching styles for the value and feature.
void setFilterValue(const QString &filterValue)
This value will be used to filter the features available from this model.
QModelIndex index(int row, int column, const QModelIndex &parent) const override
This class wraps a request for features to a vector layer (or directly its vector data provider)...
QColor backgroundColor() const
The background color for style.
static QString nullRepresentation()
This string is used to represent the value NULL throughout QGIS.
static QgsConditionalStyle compressStyles(const QList< QgsConditionalStyle > &styles)
Compress a list of styles into a single style.
void isLoadingChanged()
Indicator if the model is currently performing any feature iteration in the background.
QModelIndex parent(const QModelIndex &child) const override
void allowNullChanged()
Add a NULL entry to the list.
QgsFeatureFilterModel(QObject *parent=nullptr)
Create a new QgsFeatureFilterModel, optionally specifying a parent.
QgsExpressionContext createExpressionContext() const FINAL
This method needs to be reimplemented in all classes which implement this interface and return an exp...
static QString createFieldEqualityExpression(const QString &fieldName, const QVariant &value)
Create an expression allowing to evaluate if a field is equal to a value.
bool isLoading() const
Indicator if the model is currently performing any feature iteration in the background.
QString filterExpression() const
An additional filter expression to apply, next to the filterValue.
bool qVariantListCompare(const QVariantList &a, const QVariantList &b)
void filterExpressionChanged()
An additional filter expression to apply, next to the filterValue.
void endUpdate()
Notification that the model change is finished.
QList< QgsConditionalStyle > fieldStyles(const QString &fieldName) const
Returns the conditional styles set for the field with matching fieldName.
QString expression() const
Returns the original, unmodified expression string.
int columnCount(const QModelIndex &parent) const override
Q_DECL_DEPRECATED QString identifierField() const
The identifier field should be a unique field that can be used to identify individual features...
void extraIdentifierValueChanged()
Allows specifying one value that does not need to match the filter criteria but will still be availab...
Q_DECL_DEPRECATED void setIdentifierField(const QString &identifierField)
The identifier field should be a unique field that can be used to identify individual features...
void setSourceLayer(QgsVectorLayer *sourceLayer)
The source layer from which features will be fetched.
QColor textColor() const
The text color set for style.
void sourceLayerChanged()
The source layer from which features will be fetched.
bool validTextColor() const
Check if the text color is valid for render.
bool isField() const
Checks whether an expression consists only of a single field reference.
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 availab...
void setIdentifierFields(const QStringList &identifierFields)
The identifier field should be a unique field that can be used to identify individual features...
QgsFeatureRequest & setLimit(long limit)
Set the maximum number of features to request.
QVariant data(const QModelIndex &index, int role) const override
void setAllowNull(bool allowNull)
Add a NULL entry to the list.
QFont font() const
The font for the style.
QgsVectorLayer * sourceLayer() const
The source layer from which features will be fetched.
bool qgsVariantEqual(const QVariant &lhs, const QVariant &rhs)
Compares two QVariant values and returns whether they are equal, two NULL values are always treated a...
Definition: qgis.cpp:298
Geometry is not required. It may still be returned if e.g. required for a filter condition.
void setDisplayExpression(const QString &displayExpression)
The display expression will be used for.
Represents a vector layer which manages a vector based data sets.
QVariant attribute(const QString &name) const
Lookup attribute value from attribute name.
Definition: qgsfeature.cpp:262
void extraValueDoesNotExistChanged()
Flag indicating that the extraIdentifierValue does not exist in the data.
Used to retrieve the identifierValues (primary keys) of a feature.
QgsConditionalStyles rowStyles() const
Returns a list of row styles associated with the layer.
QgsFeatureRequest & setFlags(QgsFeatureRequest::Flags flags)
Sets flags that affect how features will be fetched.
void displayExpressionChanged()
The display expression will be used for.