QGIS API Documentation  2.14.0-Essen
qgsfeaturelistmodel.cpp
Go to the documentation of this file.
1 #include "qgsexception.h"
3 #include "qgsfeaturelistmodel.h"
7 
8 #include <QItemSelection>
9 #include <QSettings>
10 
12  : QAbstractProxyModel( parent )
13  , mInjectNull( false )
14 {
15  setSourceModel( sourceModel );
16  mExpression = new QgsExpression( "" );
17 }
18 
20 {
21  delete mExpression;
22 }
23 
25 {
27  mFilterModel = sourceModel;
28  if ( mFilterModel )
29  {
30  // rewire (filter-)change events in the source model so this proxy reflects the changes
31  connect( mFilterModel, SIGNAL( rowsAboutToBeRemoved( const QModelIndex&, int, int ) ), SLOT( onBeginRemoveRows( const QModelIndex&, int, int ) ) );
32  connect( mFilterModel, SIGNAL( rowsRemoved( const QModelIndex&, int, int ) ), SLOT( onEndRemoveRows( const QModelIndex&, int, int ) ) );
33  connect( mFilterModel, SIGNAL( rowsAboutToBeInserted( const QModelIndex&, int, int ) ), SLOT( onBeginInsertRows( const QModelIndex&, int, int ) ) );
34  connect( mFilterModel, SIGNAL( rowsInserted( const QModelIndex&, int, int ) ), SLOT( onEndInsertRows( const QModelIndex&, int, int ) ) );
35  // propagate sort order changes from source model to views connected to this model
36  connect( mFilterModel, SIGNAL( layoutAboutToBeChanged() ), this, SIGNAL( layoutAboutToBeChanged() ) );
37  connect( mFilterModel, SIGNAL( layoutChanged() ), this, SIGNAL( layoutChanged() ) );
38  }
39 }
40 
42 {
43  return mFilterModel->layerCache();
44 }
45 
47 {
48  return mFilterModel->masterModel()->rowToId( mapToMaster( index ).row() );
49 }
50 
52 {
53  return mFilterModel->mapFromMaster( mFilterModel->masterModel()->idToIndex( fid ) );
54 }
55 
57 {
58  if ( mInjectNull && index.row() == 0 )
59  {
60  if ( role == Qt::DisplayRole )
61  {
62  return QSettings().value( "qgis/nullValue", "NULL" ).toString();
63  }
64  else
65  {
66  return QVariant( QVariant::Int );
67  }
68  }
69 
70  if ( role == Qt::DisplayRole || role == Qt::EditRole )
71  {
72  QgsFeature feat;
73 
74  mFilterModel->layerCache()->featureAtId( idxToFid( index ), feat );
75 
76  QgsExpressionContext context;
79  << QgsExpressionContextUtils::layerScope( mFilterModel->layer() );
80  context.setFeature( feat );
81  return mExpression->evaluate( &context );
82  }
83 
84  if ( role == FeatureInfoRole )
85  {
86  FeatureInfo featInfo;
87 
88  QgsFeature feat;
89 
90  mFilterModel->layerCache()->featureAtId( idxToFid( index ), feat );
91 
92  QgsVectorLayerEditBuffer* editBuffer = mFilterModel->layer()->editBuffer();
93 
94  if ( editBuffer )
95  {
96  const QList<QgsFeatureId> addedFeatures = editBuffer->addedFeatures().keys();
97  const QList<QgsFeatureId> changedFeatures = editBuffer->changedAttributeValues().keys();
98 
99  if ( addedFeatures.contains( feat.id() ) )
100  {
101  featInfo.isNew = true;
102  }
103  if ( changedFeatures.contains( feat.id() ) )
104  {
105  featInfo.isEdited = true;
106  }
107  }
108 
109  return QVariant::fromValue( featInfo );
110  }
111  else if ( role == FeatureRole )
112  {
113  QgsFeature feat;
114 
115  mFilterModel->layerCache()->featureAtId( idxToFid( index ), feat );
116 
117  return QVariant::fromValue( feat );
118  }
119 
120  return sourceModel()->data( mapToSource( index ), role );
121 }
122 
124 {
125  return sourceModel()->flags( mapToSource( index ) ) & ~Qt::ItemIsEditable;
126 }
127 
129 {
130  if ( mInjectNull != injectNull )
131  {
132  emit beginResetModel();
133  mInjectNull = injectNull;
134  emit endResetModel();
135  }
136 }
137 
139 {
140  return mInjectNull;
141 }
142 
144 {
145  return mFilterModel->masterModel();
146 }
147 
149 {
150  QgsExpression* exp = new QgsExpression( expression );
151 
152  QgsExpressionContext context;
155  << QgsExpressionContextUtils::layerScope( mFilterModel->layer() );
156 
157  exp->prepare( &context );
158 
159  if ( exp->hasParserError() )
160  {
161  mParserErrorString = exp->parserErrorString();
162  delete exp;
163  return false;
164  }
165 
166  delete mExpression;
167  mExpression = exp;
168 
169  emit dataChanged( index( 0, 0 ), index( rowCount() - 1, 0 ) );
170  return true;
171 }
172 
174 {
175  return mParserErrorString;
176 }
177 
179 {
180  return mExpression->expression();
181 }
182 
184 {
185  return mFilterModel->layerCache()->featureAtId( idxToFid( index ), feat );
186 }
187 
188 void QgsFeatureListModel::onBeginRemoveRows( const QModelIndex& parent, int first, int last )
189 {
190  beginRemoveRows( parent, first, last );
191 }
192 
193 void QgsFeatureListModel::onEndRemoveRows( const QModelIndex& parent, int first, int last )
194 {
195  Q_UNUSED( parent )
196  Q_UNUSED( first )
197  Q_UNUSED( last )
198  endRemoveRows();
199 }
200 
201 void QgsFeatureListModel::onBeginInsertRows( const QModelIndex& parent, int first, int last )
202 {
203  beginInsertRows( parent, first, last );
204 }
205 
206 void QgsFeatureListModel::onEndInsertRows( const QModelIndex& parent, int first, int last )
207 {
208  Q_UNUSED( parent )
209  Q_UNUSED( first )
210  Q_UNUSED( last )
211  endInsertRows();
212 }
213 
215 {
216  if ( !proxyIndex.isValid() )
217  return QModelIndex();
218 
219  int offset = mInjectNull ? 1 : 0;
220 
221  return mFilterModel->mapToMaster( mFilterModel->index( proxyIndex.row() - offset, proxyIndex.column() ) );
222 }
223 
225 {
226  if ( !sourceIndex.isValid() )
227  return QModelIndex();
228 
229  int offset = mInjectNull ? 1 : 0;
230 
231  return createIndex( mFilterModel->mapFromMaster( sourceIndex ).row() + offset, 0 );
232 }
233 
235 {
236  return mapSelectionFromSource( mFilterModel->mapSelectionFromSource( selection ) );
237 }
238 
240 {
241  return mFilterModel->mapSelectionToSource( mapSelectionToSource( selection ) );
242 }
243 
244 // Override some methods from QAbstractProxyModel, not that interesting
245 
247 {
248  if ( !proxyIndex.isValid() )
249  return QModelIndex();
250 
251  int offset = mInjectNull ? 1 : 0;
252 
253  return sourceModel()->index( proxyIndex.row() - offset, proxyIndex.column() );
254 }
255 
257 {
258  if ( !sourceIndex.isValid() )
259  return QModelIndex();
260 
261  return createIndex( sourceIndex.row(), 0 );
262 }
263 
264 QModelIndex QgsFeatureListModel::index( int row, int column, const QModelIndex& parent ) const
265 {
266  Q_UNUSED( parent )
267 
268  return createIndex( row, column );
269 }
270 
272 {
273  Q_UNUSED( child )
274  return QModelIndex();
275 }
276 
278 {
279  Q_UNUSED( parent )
280  return 1;
281 }
282 
284 {
285  Q_UNUSED( parent )
286 
287  int offset = mInjectNull ? 1 : 0;
288 
289  return sourceModel()->rowCount() + offset;
290 }
291 
293 {
294  return mapFromMaster( masterModel()->idToIndex( fid ) );
295 }
296 
298 {
299  return QModelIndexList() << fidToIndex( fid );
300 }
QgsFeatureId id() const
Get the feature ID for this feature.
Definition: qgsfeature.cpp:65
virtual QModelIndex index(int row, int column, const QModelIndex &parent) const
bool injectNull()
Returns the current state of null value injection.
QObject * child(const char *objName, const char *inheritsClass, bool recursiveSearch) const
Class for parsing and evaluation of expressions (formerly called "search strings").
QModelIndex fidToIndex(QgsFeatureId fid) override
virtual int rowCount(const QModelIndex &parent) const =0
virtual QModelIndex mapFromSource(const QModelIndex &sourceIndex) const override
bool hasParserError() const
Returns true if an error occurred when parsing the input expression.
virtual QModelIndex index(int row, int column, const QModelIndex &parent) const =0
Q_DECL_DEPRECATED QVariant evaluate(const QgsFeature *f)
Evaluate the feature and return the result.
bool setDisplayExpression(const QString &expression)
Q_DECL_DEPRECATED bool prepare(const QgsFields &fields)
Get the expression ready for evaluation - find out column indexes.
void setFeature(const QgsFeature &feature)
Convenience function for setting a feature for the context.
virtual QModelIndex mapToMaster(const QModelIndex &proxyIndex) const
virtual int rowCount(const QModelIndex &parent=QModelIndex()) const override
virtual int columnCount(const QModelIndex &parent=QModelIndex()) const override
const QgsChangedAttributesMap & changedAttributeValues()
Changed attributes values which are not commited.
virtual QItemSelection mapSelectionFromSource(const QItemSelection &sourceSelection) const
void onEndInsertRows(const QModelIndex &parent, int first, int last)
QModelIndex idToIndex(QgsFeatureId id) const
bool featureByIndex(const QModelIndex &index, QgsFeature &feat)
virtual QItemSelection mapSelectionFromSource(const QItemSelection &sourceSelection) const
virtual QModelIndex mapFromMaster(const QModelIndex &sourceIndex) const
virtual QItemSelection mapSelectionToMaster(const QItemSelection &selection) const
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:187
A model backed by a QgsVectorLayerCache which is able to provide feature/attribute information to a Q...
void rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end)
QString parserErrorString()
Returns a detailed message about errors while parsing a QgsExpression.
virtual void setSourceModel(QgsAttributeTableFilterModel *sourceModel)
void onBeginInsertRows(const QModelIndex &parent, int first, int last)
virtual QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const override
QgsVectorLayer * layer() const
Returns the layer this filter acts on.
QList< Key > keys() const
void layoutAboutToBeChanged()
bool isValid() const
QgsVectorLayerEditBuffer * editBuffer()
Buffer with uncommitted editing operations. Only valid after editing has been turned on...
void rowsAboutToBeInserted(const QModelIndex &parent, int start, int end)
static QgsExpressionContextScope * globalScope()
Creates a new scope which contains variables and functions relating to the global QGIS context...
QgsVectorLayerCache * layerCache() const
Returns the layerCache this filter acts on.
virtual QModelIndex mapToSource(const QModelIndex &proxyIndex) const override
void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
virtual QModelIndex mapToMaster(const QModelIndex &proxyIndex) const
virtual QVariant data(const QModelIndex &index, int role) const override
virtual QItemSelection mapSelectionToSource(const QItemSelection &proxySelection) const
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
void beginRemoveRows(const QModelIndex &parent, int first, int last)
int row() const
QModelIndexList fidToIndexList(QgsFeatureId fid)
virtual void setSourceModel(QAbstractItemModel *sourceModel)
virtual QVariant data(const QModelIndex &index, int role) const =0
virtual Qt::ItemFlags flags(const QModelIndex &index) const override
void rowsRemoved(const QModelIndex &parent, int start, int end)
QModelIndex createIndex(int row, int column, void *ptr) const
QgsAttributeTableModel * masterModel()
virtual QItemSelection mapSelectionToSource(const QItemSelection &proxySelection) const
void onBeginRemoveRows(const QModelIndex &parent, int first, int last)
This class caches features of a given QgsVectorLayer.
bool contains(const T &value) const
QVariant fromValue(const T &value)
void beginInsertRows(const QModelIndex &parent, int first, int last)
const QgsFeatureMap & addedFeatures()
New features which are not commited.
QVariant value(const QString &key, const QVariant &defaultValue) const
QAbstractItemModel * sourceModel() const
QgsAttributeTableModel * masterModel() const
Returns the table model this filter is using.
virtual QModelIndex mapFromMaster(const QModelIndex &sourceIndex) const
bool featureAtId(QgsFeatureId featureId, QgsFeature &feature, bool skipCache=false)
Gets the feature at the given feature id.
QgsFeatureId idxToFid(const QModelIndex &index) const
int column() const
qint64 QgsFeatureId
Definition: qgsfeature.h:31
void onEndRemoveRows(const QModelIndex &parent, int first, int last)
QString expression() const
Return the original, unmodified expression string.
QgsVectorLayerCache * layerCache()
virtual Qt::ItemFlags flags(const QModelIndex &index) const
void setInjectNull(bool injectNull)
If true is specified, a NULL value will be injected.
QgsFeatureId rowToId(int row) const
Maps row to feature id.
static QgsExpressionContextScope * projectScope()
Creates a new scope which contains variables and functions relating to the current QGIS project...
static QgsExpressionContextScope * layerScope(const QgsMapLayer *layer)
Creates a new scope which contains variables and functions relating to a QgsMapLayer.
void rowsInserted(const QModelIndex &parent, int start, int end)
QModelIndex fidToIdx(const QgsFeatureId fid) const
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QObject * parent() const
QString parserErrorString() const
Returns parser error.
virtual QItemSelection mapSelectionFromMaster(const QItemSelection &selection) const
QString toString() const
QgsFeatureListModel(QgsAttributeTableFilterModel *sourceModel, QObject *parent=nullptr)
QString displayExpression() const
typedef ItemFlags