QGIS API Documentation  2.9.0-Master
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
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 {
26  QAbstractProxyModel::setSourceModel( sourceModel );
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 
51 QModelIndex QgsFeatureListModel::fidToIdx( const QgsFeatureId fid ) const
52 {
53  return mFilterModel->mapFromMaster( mFilterModel->masterModel()->idToIndex( fid ) );
54 }
55 
56 QVariant QgsFeatureListModel::data( const QModelIndex &index, int role ) const
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  const QgsFields fields = mFilterModel->layer()->pendingFields();
77 
78  return mExpression->evaluate( &feat, fields );
79  }
80 
81  if ( role == FeatureInfoRole )
82  {
83  FeatureInfo featInfo;
84 
85  QgsFeature feat;
86 
87  mFilterModel->layerCache()->featureAtId( idxToFid( index ), feat );
88 
89  QgsVectorLayerEditBuffer* editBuffer = mFilterModel->layer()->editBuffer();
90 
91  if ( editBuffer )
92  {
93  const QList<QgsFeatureId> addedFeatures = editBuffer->addedFeatures().keys();
94  const QList<QgsFeatureId> changedFeatures = editBuffer->changedAttributeValues().keys();
95 
96  if ( addedFeatures.contains( feat.id() ) )
97  {
98  featInfo.isNew = true;
99  }
100  if ( changedFeatures.contains( feat.id() ) )
101  {
102  featInfo.isEdited = true;
103  }
104  }
105 
106  return QVariant::fromValue( featInfo );
107  }
108  else if ( role == FeatureRole )
109  {
110  QgsFeature feat;
111 
112  mFilterModel->layerCache()->featureAtId( idxToFid( index ), feat );
113 
114  return QVariant::fromValue( feat );
115  }
116 
117  return sourceModel()->data( mapToSource( index ), role );
118 }
119 
120 Qt::ItemFlags QgsFeatureListModel::flags( const QModelIndex &index ) const
121 {
122  return sourceModel()->flags( mapToSource( index ) ) & ~Qt::ItemIsEditable;
123 }
124 
125 void QgsFeatureListModel::setInjectNull( bool injectNull )
126 {
127  if ( mInjectNull != injectNull )
128  {
129  emit beginResetModel();
130  mInjectNull = injectNull;
131  emit endResetModel();
132  }
133 }
134 
136 {
137  return mInjectNull;
138 }
139 
141 {
142  return mFilterModel->masterModel();
143 }
144 
145 bool QgsFeatureListModel::setDisplayExpression( const QString expression )
146 {
147  const QgsFields fields = mFilterModel->layer()->dataProvider()->fields();
148 
149  QgsExpression* exp = new QgsExpression( expression );
150 
151  exp->prepare( fields );
152 
153  if ( exp->hasParserError() )
154  {
155  mParserErrorString = exp->parserErrorString();
156  delete exp;
157  return false;
158  }
159 
160  delete mExpression;
161  mExpression = exp;
162 
163  emit dataChanged( index( 0, 0 ), index( rowCount() - 1, 0 ) );
164  return true;
165 }
166 
168 {
169  return mParserErrorString;
170 }
171 
173 {
174  return mExpression->expression();
175 }
176 
177 bool QgsFeatureListModel::featureByIndex( const QModelIndex &index, QgsFeature &feat )
178 {
179  return mFilterModel->layerCache()->featureAtId( idxToFid( index ), feat );
180 }
181 
182 void QgsFeatureListModel::onBeginRemoveRows( const QModelIndex& parent, int first, int last )
183 {
184  beginRemoveRows( parent, first, last );
185 }
186 
187 void QgsFeatureListModel::onEndRemoveRows( const QModelIndex& parent, int first, int last )
188 {
189  Q_UNUSED( parent )
190  Q_UNUSED( first )
191  Q_UNUSED( last )
192  endRemoveRows();
193 }
194 
195 void QgsFeatureListModel::onBeginInsertRows( const QModelIndex& parent, int first, int last )
196 {
197  beginInsertRows( parent, first, last );
198 }
199 
200 void QgsFeatureListModel::onEndInsertRows( const QModelIndex& parent, int first, int last )
201 {
202  Q_UNUSED( parent )
203  Q_UNUSED( first )
204  Q_UNUSED( last )
205  endInsertRows();
206 }
207 
208 QModelIndex QgsFeatureListModel::mapToMaster( const QModelIndex &proxyIndex ) const
209 {
210  if ( !proxyIndex.isValid() )
211  return QModelIndex();
212 
213  int offset = mInjectNull ? 1 : 0;
214 
215  return mFilterModel->mapToMaster( mFilterModel->index( proxyIndex.row() - offset, proxyIndex.column() ) );
216 }
217 
218 QModelIndex QgsFeatureListModel::mapFromMaster( const QModelIndex &sourceIndex ) const
219 {
220  if ( !sourceIndex.isValid() )
221  return QModelIndex();
222 
223  int offset = mInjectNull ? 1 : 0;
224 
225  return createIndex( mFilterModel->mapFromMaster( sourceIndex ).row() + offset, 0 );
226 }
227 
228 QItemSelection QgsFeatureListModel::mapSelectionFromMaster( const QItemSelection& selection ) const
229 {
230  return mapSelectionFromSource( mFilterModel->mapSelectionFromSource( selection ) );
231 }
232 
233 QItemSelection QgsFeatureListModel::mapSelectionToMaster( const QItemSelection& selection ) const
234 {
235  return mFilterModel->mapSelectionToSource( mapSelectionToSource( selection ) );
236 }
237 
238 // Override some methods from QAbstractProxyModel, not that interesting
239 
240 QModelIndex QgsFeatureListModel::mapToSource( const QModelIndex &proxyIndex ) const
241 {
242  if ( !proxyIndex.isValid() )
243  return QModelIndex();
244 
245  int offset = mInjectNull ? 1 : 0;
246 
247  return sourceModel()->index( proxyIndex.row() - offset, proxyIndex.column() );
248 }
249 
250 QModelIndex QgsFeatureListModel::mapFromSource( const QModelIndex &sourceIndex ) const
251 {
252  if ( !sourceIndex.isValid() )
253  return QModelIndex();
254 
255  return createIndex( sourceIndex.row(), 0 );
256 }
257 
258 QModelIndex QgsFeatureListModel::index( int row, int column, const QModelIndex& parent ) const
259 {
260  Q_UNUSED( parent )
261 
262  return createIndex( row, column );
263 }
264 
265 QModelIndex QgsFeatureListModel::parent( const QModelIndex& child ) const
266 {
267  Q_UNUSED( child )
268  return QModelIndex();
269 }
270 
271 int QgsFeatureListModel::columnCount( const QModelIndex&parent ) const
272 {
273  Q_UNUSED( parent )
274  return 1;
275 }
276 
277 int QgsFeatureListModel::rowCount( const QModelIndex& parent ) const
278 {
279  Q_UNUSED( parent )
280 
281  int offset = mInjectNull ? 1 : 0;
282 
283  return sourceModel()->rowCount() + offset;
284 }
285 
287 {
288  return mapFromMaster( masterModel()->idToIndex( fid ) );
289 }
290 
292 {
293  return QModelIndexList() << fidToIndex( fid );
294 }
QgsFeatureId id() const
Get the feature id for this feature.
Definition: qgsfeature.cpp:100
bool injectNull()
Returns the current state of null value injection.
Class for parsing and evaluation of expressions (formerly called "search strings").
Definition: qgsexpression.h:87
QModelIndex fidToIndex(QgsFeatureId fid) override
static unsigned index
virtual QModelIndex mapFromSource(const QModelIndex &sourceIndex) const override
bool hasParserError() const
Returns true if an error occurred when parsing the input expression.
Definition: qgsexpression.h:94
const QString expression() const
Alias for dump()
QVariant evaluate(const QgsFeature *f=NULL)
Evaluate the feature and return the result.
bool prepare(const QgsFields &fields)
Get the expression ready for evaluation - find out column indexes.
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.
void onEndInsertRows(const QModelIndex &parent, int first, int last)
QModelIndex idToIndex(QgsFeatureId id) const
bool featureByIndex(const QModelIndex &index, QgsFeature &feat)
Container of fields for a vector layer.
Definition: qgsfield.h:172
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:113
A model backed by a QgsVectorLayerCache which is able to provide feature/attribute information to a Q...
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.
QgsVectorLayerEditBuffer * editBuffer()
Buffer with uncommitted editing operations. Only valid after editing has been turned on...
QgsVectorLayerCache * layerCache() const
Returns the layerCache this filter acts on.
virtual QModelIndex mapToSource(const QModelIndex &proxyIndex) const override
bool setDisplayExpression(const QString expression)
virtual QModelIndex mapToMaster(const QModelIndex &proxyIndex) const
virtual QVariant data(const QModelIndex &index, int role) const override
QModelIndexList fidToIndexList(QgsFeatureId fid)
virtual Qt::ItemFlags flags(const QModelIndex &index) const override
QgsAttributeTableModel * masterModel()
void onBeginRemoveRows(const QModelIndex &parent, int first, int last)
This class caches features of a given QgsVectorLayer.
const QgsFeatureMap & addedFeatures()
New features which are not commited.
QgsAttributeTableModel * masterModel() const
Returns the table model this filter is using.
virtual const QgsFields & fields() const =0
Return a map of indexes with field names for this layer.
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
qint64 QgsFeatureId
Definition: qgsfeature.h:30
void onEndRemoveRows(const QModelIndex &parent, int first, int last)
QgsVectorLayerCache * layerCache()
void setInjectNull(bool injectNull)
If true is specified, a NULL value will be injected.
QgsFeatureId rowToId(int row) const
Maps row to feature id.
const QgsFields & pendingFields() const
returns field list in the to-be-committed state
virtual QModelIndex parent(const QModelIndex &child) const override
QgsVectorDataProvider * dataProvider()
Returns the data provider.
QModelIndex fidToIdx(const QgsFeatureId fid) const
QgsFeatureListModel(QgsAttributeTableFilterModel *sourceModel, QObject *parent=0)
QString parserErrorString() const
Returns parser error.
Definition: qgsexpression.h:96
virtual QItemSelection mapSelectionFromMaster(const QItemSelection &selection) const
QString displayExpression() const