16 #include <QItemSelectionModel>
39 : QSortFilterProxyModel( parent )
43 setDynamicSortFilter(
true );
47 mReloadVisibleTimer.setSingleShot(
true );
48 connect( &mReloadVisibleTimer, &QTimer::timeout,
this, &QgsAttributeTableFilterModel::reloadVisible );
49 mFilterFeaturesTimer.setSingleShot(
true );
60 if ( leftSelected && !rightSelected )
62 return sortOrder() == Qt::AscendingOrder;
64 else if ( rightSelected && !leftSelected )
66 return sortOrder() == Qt::DescendingOrder;
82 if ( order != Qt::AscendingOrder && order != Qt::DescendingOrder )
83 order = Qt::AscendingOrder;
84 if ( column < 0 || column >= mColumnMapping.size() )
90 const int myColumn = mColumnMapping.at( column );
92 QSortFilterProxyModel::sort( myColumn, order );
99 if ( mapColumnToSource( index.column() ) == -1 )
105 const QModelIndex fieldIndex = QSortFilterProxyModel::mapToSource( QSortFilterProxyModel::index( index.row(), 0, index.parent() ) );
112 return QSortFilterProxyModel::data( index, role );
117 if ( orientation == Qt::Horizontal )
119 if ( mColumnMapping.at( section ) == -1 && role == Qt::DisplayRole )
120 return tr(
"Actions" );
122 return QSortFilterProxyModel::headerData( section, orientation, role );
126 if ( role == Qt::DisplayRole )
130 const int sourceSection =
mapToSource( index( section, ( !mColumnMapping.isEmpty() && mColumnMapping.at( 0 ) == -1 ) ? 1 : 0 ) ).row();
131 return sourceModel()->headerData( sourceSection, orientation, role );
138 return mColumnMapping.indexOf( -1 );
144 return mColumnMapping.count();
158 QVector<int> newColumnMapping;
159 const auto constColumns = mConfig.
columns();
163 if ( columnConfig.hidden )
168 newColumnMapping << newValue;
171 if ( newColumnMapping != mColumnMapping )
173 bool requiresReset =
false;
174 int firstRemovedColumn = -1;
175 int removedColumnCount = 0;
178 for (
int i = 0; i < std::min( newColumnMapping.size(), mColumnMapping.size() - removedColumnCount ); ++i )
180 if ( newColumnMapping.at( i ) == mColumnMapping.at( i + removedColumnCount ) )
183 if ( firstRemovedColumn == -1 )
185 firstRemovedColumn = i;
187 while ( i < mColumnMapping.size() - removedColumnCount && mColumnMapping.at( i + removedColumnCount ) != newColumnMapping.at( i ) )
189 ++removedColumnCount;
194 requiresReset =
true;
200 if ( firstRemovedColumn == -1 )
202 if ( newColumnMapping.size() > mColumnMapping.size() )
205 beginInsertColumns( QModelIndex(), mColumnMapping.size(), newColumnMapping.size() - 1 );
206 mColumnMapping = newColumnMapping;
212 beginRemoveColumns( QModelIndex(), newColumnMapping.size(), mColumnMapping.size() - 1 );
213 mColumnMapping = newColumnMapping;
219 if ( newColumnMapping.size() == mColumnMapping.size() - removedColumnCount )
222 beginRemoveColumns( QModelIndex(), firstRemovedColumn, firstRemovedColumn + removedColumnCount - 1 );
223 mColumnMapping = newColumnMapping;
228 requiresReset =
true;
235 mColumnMapping = newColumnMapping;
246 mFilterExpression = expression;
247 mFilterExpressionContext = context;
252 if ( order != Qt::AscendingOrder && order != Qt::DescendingOrder )
253 order = Qt::AscendingOrder;
255 QSortFilterProxyModel::sort( -1 );
257 QSortFilterProxyModel::sort( 0, order );
270 int column = sortColumn();
271 Qt::SortOrder order = sortOrder();
277 if ( order != Qt::AscendingOrder && order != Qt::DescendingOrder )
278 order = Qt::AscendingOrder;
280 sort( 0, Qt::AscendingOrder );
287 mTableModel = sourceModel;
291 mColumnMapping.append( i );
294 QSortFilterProxyModel::setSourceModel( sourceModel );
297 disconnect( mTableModel, SIGNAL( columnsAboutToBeInserted( QModelIndex,
int,
int ) ),
this, SLOT( _q_sourceColumnsAboutToBeInserted( QModelIndex,
int,
int ) ) );
298 disconnect( mTableModel, SIGNAL( columnsInserted( QModelIndex,
int,
int ) ),
this, SLOT( _q_sourceColumnsInserted( QModelIndex,
int,
int ) ) );
299 disconnect( mTableModel, SIGNAL( columnsAboutToBeRemoved( QModelIndex,
int,
int ) ),
this, SLOT( _q_sourceColumnsAboutToBeRemoved( QModelIndex,
int,
int ) ) );
300 disconnect( mTableModel, SIGNAL( columnsRemoved( QModelIndex,
int,
int ) ),
this, SLOT( _q_sourceColumnsRemoved( QModelIndex,
int,
int ) ) );
302 connect( mTableModel, &QAbstractItemModel::columnsAboutToBeInserted,
this, &QgsAttributeTableFilterModel::onColumnsChanged );
303 connect( mTableModel, &QAbstractItemModel::columnsAboutToBeRemoved,
this, &QgsAttributeTableFilterModel::onColumnsChanged );
309 return mSelectedOnTop;
314 mFilteredFeatures = ids;
322 ids.reserve( rowCount() );
323 for (
int i = 0; i < rowCount(); ++i )
325 const QModelIndex row = index( i, 0 );
345 switch ( mFilterMode )
391 Q_UNUSED( sourceParent )
392 switch ( mFilterMode )
439 void QgsAttributeTableFilterModel::reloadVisible()
446 void QgsAttributeTableFilterModel::onAttributeValueChanged(
QgsFeatureId fid,
int idx,
const QVariant &value )
453 startTimedFilterFeatures();
457 void QgsAttributeTableFilterModel::onGeometryChanged()
461 startTimedFilterFeatures();
465 void QgsAttributeTableFilterModel::startTimedReloadVisible()
467 mReloadVisibleTimer.start( 10 );
470 void QgsAttributeTableFilterModel::startTimedFilterFeatures()
472 mFilterFeaturesTimer.start( 10 );
477 if ( !mFilterExpression.
isValid() )
488 QApplication::setOverrideCursor( Qt::WaitCursor );
514 if ( mFilterExpression.
evaluate( &mFilterExpressionContext ).toInt() != 0 )
518 if ( mFilterExpression.
hasEvalError() && error.isEmpty() )
528 QApplication::restoreOverrideCursor();
532 if ( ! error.isEmpty() )
540 void QgsAttributeTableFilterModel::selectionChanged()
546 else if ( mSelectedOnTop )
552 void QgsAttributeTableFilterModel::onColumnsChanged()
557 int QgsAttributeTableFilterModel::mapColumnToSource(
int column )
const
559 if ( mColumnMapping.isEmpty() )
561 if ( column < 0 || column >= mColumnMapping.size() )
564 return mColumnMapping.at( column );
567 int QgsAttributeTableFilterModel::mapColumnFromSource(
int column )
const
569 if ( mColumnMapping.isEmpty() )
572 return mColumnMapping.indexOf( column );
585 mFilteredFeatures.clear();
586 if ( !
layer()->renderer() )
588 QgsDebugMsg( QStringLiteral(
"Cannot get renderer" ) );
592 std::unique_ptr< QgsFeatureRenderer > renderer(
layer()->renderer()->clone() );
597 QgsDebugMsg( QStringLiteral(
"Out of scale limits" ) );
615 renderer->startRender( renderContext,
layer()->fields() );
634 const QString temporalFilter = qobject_cast< const QgsVectorLayerTemporalProperties * >(
layer()->temporalProperties() )->createFilterString( temporalContext, mCanvas->
mapSettings().
temporalRange() );
635 if ( !temporalFilter.isEmpty() )
646 if ( !filter || renderer->willRenderFeature( f, renderContext ) )
648 mFilteredFeatures << f.
id();
651 if ( t.elapsed() > 5000 )
654 emit progress( i, cancel );
667 renderer->stopRender( renderContext );
683 QModelIndexList indexes;
685 for (
const QModelIndex &idx : constIdToIndexList )
695 if ( !proxyIndex.isValid() )
696 return QModelIndex();
698 int sourceColumn = mapColumnToSource( proxyIndex.column() );
702 if ( sourceColumn == -1 )
705 return QSortFilterProxyModel::mapToSource( index( proxyIndex.row(), sourceColumn, proxyIndex.parent() ) );
710 const QModelIndex proxyIndex = QSortFilterProxyModel::mapFromSource( sourceIndex );
712 if ( proxyIndex.column() < 0 )
713 return QModelIndex();
715 int col = mapColumnFromSource( proxyIndex.column() );
720 return index( proxyIndex.row(), col, proxyIndex.parent() );
726 if ( mapColumnToSource( index.column() ) == -1 )
727 return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
729 const QModelIndex source_index =
mapToSource( index );
@ BoundingBox
Filter using a bounding box.
This is a container for configuration of the attribute table.
@ Action
This column represents an action widget.
Qt::SortOrder sortOrder() const
Gets the sort order.
QVector< QgsAttributeTableConfig::ColumnConfig > columns() const
Gets the list with all columns and their configuration.
void update(const QgsFields &fields)
Update the configuration with the given fields.
QString sortExpression() const
Gets the expression used for sorting.
bool hasSameColumns(const QgsAttributeTableConfig &other) const
Compare this configuration's columns name, type, and order to other.
QModelIndex mapToSource(const QModelIndex &proxyIndex) const override
QString sortExpression() const
The expression which is used to sort the attribute table.
FilterMode filterMode()
The current filterModel.
QModelIndex mapFromSource(const QModelIndex &sourceIndex) const override
@ TypeRole
The type of a given column.
Q_DECL_DEPRECATED void extentsChanged()
Is called upon every change of the visible extents on the map canvas.
void sort(int column, Qt::SortOrder order=Qt::AscendingOrder) override
Sort by the given column using the given order.
QgsAttributeTableFilterModel(QgsMapCanvas *canvas, QgsAttributeTableModel *sourceModel, QObject *parent=nullptr)
Make sure, the master model is already loaded, so the selection will get synchronized.
QgsVectorLayer * layer() const
Returns the layer this filter acts on.
void setFilterMode(FilterMode filterMode)
Set the filter mode the filter will use.
int columnCount(const QModelIndex &parent) const override
void setAttributeTableConfig(const QgsAttributeTableConfig &config, bool force=false)
Set the attribute table configuration to control which fields are shown, in which order they are show...
void generateListOfVisibleFeatures()
Updates the list of currently visible features on the map canvas.
QModelIndexList fidToIndexList(QgsFeatureId fid)
void disconnectFilterModeConnections()
Disconnect the connections set for the current filterMode.
QModelIndex fidToIndex(QgsFeatureId fid) override
bool lessThan(const QModelIndex &left, const QModelIndex &right) const override
Used by the sorting algorithm.
FilterMode
The filter mode defines how the rows should be filtered.
@ ShowFilteredList
Show only features whose ids are on the filter list. {.
@ ShowVisible
Show only visible features (depends on the map canvas)
@ ShowSelected
Show only selected features.
@ ShowEdited
Show only features which have unsaved changes.
@ ShowAll
Show all features.
bool selectedOnTop()
Returns if selected features are currently shown on top.
void filterError(const QString &errorMessage)
Emitted when an error occurred while filtering features.
bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override
Returns true if the source row will be accepted.
QModelIndex mapFromMaster(const QModelIndex &sourceIndex) const
void filterFeatures()
Updates the filtered features in the filter model.
int actionColumnIndex() const
Gets the index of the first column that contains an action widget.
void setFilterExpression(const QgsExpression &expression, const QgsExpressionContext &context)
Set the expression and the context to be stored in case of the features need to be filtered again (li...
virtual void setFilteredFeatures(const QgsFeatureIds &ids)
Specify a list of features, which the filter will accept.
QgsFeatureId rowToId(const QModelIndex &row)
Returns the feature id for a given model index.
QVariant headerData(int section, Qt::Orientation orientation, int role) const override
QVariant data(const QModelIndex &index, int role) const override
void featuresFiltered()
Emitted when the filtering of the features has been done.
void visibleReloaded()
Emitted when the the visible features on extend are reloaded (the list is created)
@ ColumnTypeActionButton
This column shows action buttons.
@ ColumnTypeField
This column shows a field.
QgsFeatureIds filteredFeatures()
Gets a list of currently filtered feature ids.
void setSourceModel(QgsAttributeTableModel *sourceModel)
Set the attribute table model that backs this model.
void setSelectedOnTop(bool selectedOnTop)
Changes the sort order of the features.
QgsAttributeTableModel * masterModel() const
Returns the table model this filter is using.
void sortColumnChanged(int column, Qt::SortOrder order)
Emitted whenever the sort column is changed.
void connectFilterModeConnections(FilterMode filterMode)
Disconnect the connections set for the new filterMode.
Qt::ItemFlags flags(const QModelIndex &index) const override
A model backed by a QgsVectorLayerCache which is able to provide feature/attribute information to a Q...
const QgsFeatureRequest & request() const
Gets the the feature request.
Qt::ItemFlags flags(const QModelIndex &index) const override
Returns item flags for the index.
QgsVectorLayer * layer() const
Returns the layer this model uses as backend.
QString sortCacheExpression(unsigned long cacheIndex=0) const
The expression which was used to fill the sorting cache at index cacheIndex.
QgsVectorLayerCache * layerCache() const
Returns the layer cache this model uses as backend.
int extraColumns() const
Empty extra columns to announce from this model.
int columnCount(const QModelIndex &parent=QModelIndex()) const override
Returns the number of columns.
QModelIndexList idToIndexList(QgsFeatureId id) const
void prefetchSortData(const QString &expression, unsigned long cacheIndex=0)
Prefetches the entire data for an expression.
QgsFeatureId rowToId(int row) const
Maps row to feature id.
@ SortRole
Role used for sorting start here.
@ FeatureIdRole
Get the feature id of the feature in this row.
void prefetchColumnData(int column)
Caches the entire data for one column.
A general purpose distance and area calculator, capable of performing ellipsoid based calculations.
void setSourceCrs(const QgsCoordinateReferenceSystem &crs, const QgsCoordinateTransformContext &context)
Sets source spatial reference system crs.
bool setEllipsoid(const QString &ellipsoid)
Sets the ellipsoid by its acronym.
static QList< QgsExpressionContextScope * > globalProjectLayerScopes(const QgsMapLayer *layer)
Creates a list of three scopes: global, layer's project and layer.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
void setFeature(const QgsFeature &feature)
Convenience function for setting a feature for the context.
void appendScopes(const QList< QgsExpressionContextScope * > &scopes)
Appends a list of scopes to the end of the context.
Class for parsing and evaluation of expressions (formerly called "search strings").
QString evalErrorString() const
Returns evaluation error.
void setDistanceUnits(QgsUnitTypes::DistanceUnit unit)
Sets the desired distance units for calculations involving geomCalculator(), e.g.,...
QSet< QString > referencedColumns() const
Gets list of columns referenced by the expression.
void setAreaUnits(QgsUnitTypes::AreaUnit unit)
Sets the desired areal units for calculations involving geomCalculator(), e.g., "$area".
void setGeomCalculator(const QgsDistanceArea *calc)
Sets the geometry calculator used for distance and area calculations in expressions.
bool hasEvalError() const
Returns true if an error occurred when evaluating last input.
bool needsGeometry() const
Returns true if the expression uses feature geometry for some computation.
QVariant evaluate()
Evaluate the feature and return the result.
bool isValid() const
Checks if this expression is valid.
QSet< int > referencedAttributeIndexes(const QgsFields &fields) const
Returns a list of field name indexes obtained from the provided fields.
Wrapper for iterator of features from vector data provider or vector layer.
bool nextFeature(QgsFeature &f)
@ ScaleDependent
Depends on scale if feature will be rendered (rule based )
@ Filter
Features may be filtered, i.e. some features may not be rendered (categorized, rule based ....
This class wraps a request for features to a vector layer (or directly its vector data provider).
QgsRectangle filterRect() const
Returns the rectangle from which features will be taken.
QgsFeatureRequest & setFlags(QgsFeatureRequest::Flags flags)
Sets flags that affect how features will be fetched.
Flags flags() const
Returns the flags which affect how features are fetched.
QgsFeatureRequest & setSubsetOfAttributes(const QgsAttributeList &attrs)
Set a subset of attributes that will be fetched.
QgsFeatureRequest & setFilterExpression(const QString &expression)
Set the filter expression.
@ NoGeometry
Geometry is not required. It may still be returned if e.g. required for a filter condition.
Qgis::SpatialFilterType spatialFilterType() const
Returns the spatial filter type which is currently set on this request.
QgsFeatureRequest & setFilterRect(const QgsRectangle &rectangle)
Sets the rectangle from which features will be taken.
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
int lookupField(const QString &fieldName) const
Looks up field's index from the field name.
Map canvas is a class for displaying all GIS data types on a canvas.
void extentsChanged()
Emitted when the extents of the map change.
void temporalRangeChanged()
Emitted when the map canvas temporal range changes.
const QgsMapSettings & mapSettings() const
Gets access to properties used for map rendering.
QgsRectangle extent() const
Returns the current zoom extent of the map canvas.
QgsCoordinateReferenceSystem crs
The QgsMapSettings class contains configuration for rendering of the map.
double scale() const
Returns the calculated map scale.
const QgsMapToPixel & mapToPixel() const
QgsRectangle visibleExtent() const
Returns the actual extent derived from requested extent that takes output image size into account.
QgsPointXY mapToLayerCoordinates(const QgsMapLayer *layer, QgsPointXY point) const
transform point coordinates from output CRS to layer's CRS
static QgsProject * instance()
Returns the QgsProject singleton instance.
QgsCoordinateTransformContext transformContext
A rectangle specified with double values.
QgsRectangle intersect(const QgsRectangle &rect) const
Returns the intersection with the given rectangle.
Contains information about the context of a rendering operation.
QgsExpressionContext & expressionContext()
Gets the expression context.
void setExtent(const QgsRectangle &extent)
When rendering a map layer, calling this method sets the "clipping" extent for the layer (in the laye...
void setMapToPixel(const QgsMapToPixel &mtp)
Sets the context's map to pixel transform, which transforms between map coordinates and device coordi...
void setRendererScale(double scale)
Sets the renderer map scale.
const QgsDateTimeRange & temporalRange() const
Returns the datetime range for the object.
bool isTemporal() const
Returns true if the object's temporal range is enabled, and the object will be filtered when renderin...
QgsFeatureIterator getFeatures(const QgsFeatureRequest &featureRequest=QgsFeatureRequest())
Query this VectorLayerCache for features.
bool isFeatureAdded(QgsFeatureId id) const
Returns true if the specified feature ID has been added but not committed.
bool isFeatureAttributesChanged(QgsFeatureId id) const
Returns true if the specified feature ID has had an attribute changed but not committed.
bool isFeatureGeometryChanged(QgsFeatureId id) const
Returns true if the specified feature ID has had its geometry changed but not committed.
Encapsulates the context in which a QgsVectorLayer's temporal capabilities will be applied.
void setLayer(QgsVectorLayer *layer)
Sets the associated layer.
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const FINAL
Queries the layer for features specified in request.
QgsFields fields() const FINAL
Returns the list of fields of this layer.
Q_INVOKABLE const QgsFeatureIds & selectedFeatureIds() const
Returns a list of the selected features IDs in this layer.
void attributeValueChanged(QgsFeatureId fid, int idx, const QVariant &value)
Emitted whenever an attribute value change is done in the edit buffer.
void selectionChanged(const QgsFeatureIds &selected, const QgsFeatureIds &deselected, bool clearAndSelect)
Emitted when selection was changed.
void featureAdded(QgsFeatureId fid)
Emitted when a new feature has been added to the layer.
Q_INVOKABLE QgsVectorLayerEditBuffer * editBuffer()
Buffer with uncommitted editing operations. Only valid after editing has been turned on.
void geometryChanged(QgsFeatureId fid, const QgsGeometry &geometry)
Emitted whenever a geometry change is done in the edit buffer.
bool qgsVariantLessThan(const QVariant &lhs, const QVariant &rhs)
Compares two QVariant values and returns whether the first is less than the second.
QSet< QgsFeatureId > QgsFeatureIds
qint64 QgsFeatureId
64 bit feature ids negative numbers are used for uncommitted/newly added features
Defines the configuration of a column in the attribute table.