QGIS API Documentation  2.0.1-Dufour
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
qgsfeaturelistmodel.cpp
Go to the documentation of this file.
1 #include "qgsexception.h"
3 #include "qgsfeaturelistmodel.h"
7 
8 #include <QItemSelection>
9 
11  : QAbstractProxyModel( parent )
12 {
13  setSourceModel( sourceModel );
14  mExpression = new QgsExpression( "" );
15 }
16 
18 {
19  delete mExpression;
20 }
21 
23 {
25  mFilterModel = sourceModel;
26  if ( mFilterModel )
27  {
28  // rewire (filter-)change events in the source model so this proxy reflects the changes
29  connect( mFilterModel, SIGNAL( rowsAboutToBeRemoved( const QModelIndex&, int, int ) ), SLOT( onBeginRemoveRows( const QModelIndex&, int, int ) ) );
30  connect( mFilterModel, SIGNAL( rowsRemoved( const QModelIndex&, int, int ) ), SLOT( onEndRemoveRows( const QModelIndex&, int, int ) ) );
31  connect( mFilterModel, SIGNAL( rowsAboutToBeInserted( const QModelIndex&, int, int ) ), SLOT( onBeginInsertRows( const QModelIndex&, int, int ) ) );
32  connect( mFilterModel, SIGNAL( rowsInserted( const QModelIndex&, int, int ) ), SLOT( onEndInsertRows( const QModelIndex&, int, int ) ) );
33  // propagate sort order changes from source model to views connected to this model
34  connect( mFilterModel, SIGNAL( layoutAboutToBeChanged() ), this, SIGNAL( layoutAboutToBeChanged() ) );
35  connect( mFilterModel, SIGNAL( layoutChanged() ), this, SIGNAL( layoutChanged() ) );
36  }
37 }
38 
40 {
41  return mFilterModel->layerCache();
42 }
43 
44 QgsFeatureId QgsFeatureListModel::idxToFid( const QModelIndex &index ) const
45 {
46  return mFilterModel->masterModel()->rowToId( mapToMaster( index ).row() );
47 }
48 
49 QModelIndex QgsFeatureListModel::fidToIdx( const QgsFeatureId fid ) const
50 {
52 }
53 
54 QVariant QgsFeatureListModel::data( const QModelIndex &index, int role ) const
55 {
56  if ( role == Qt::DisplayRole || role == Qt::EditRole )
57  {
58  QgsFeature feat;
59 
60  mFilterModel->layerCache()->featureAtId( idxToFid( index ), feat );
61 
62  const QgsFields fields = mFilterModel->layer()->pendingFields();
63 
64  return mExpression->evaluate( &feat, fields );
65  }
66 
67  if ( role == Qt::UserRole )
68  {
69  FeatureInfo featInfo;
70 
71  QgsFeature feat;
72 
73  mFilterModel->layerCache()->featureAtId( idxToFid( index ), feat );
74 
76 
77  if ( editBuffer )
78  {
79  const QList<QgsFeatureId> addedFeatures = editBuffer->addedFeatures().keys();
80  const QList<QgsFeatureId> changedFeatures = editBuffer->changedAttributeValues().keys();
81 
82  if ( addedFeatures.contains( feat.id() ) )
83  {
84  featInfo.isNew = true;
85  }
86  if ( changedFeatures.contains( feat.id() ) )
87  {
88  featInfo.isEdited = true;
89  }
90  }
91 
92  return QVariant::fromValue( featInfo );
93  }
94 
95  return sourceModel()->data( mapToSource( index ), role );
96 }
97 
98 Qt::ItemFlags QgsFeatureListModel::flags( const QModelIndex &index ) const
99 {
100  return sourceModel()->flags( mapToSource( index ) ) & ~Qt::ItemIsEditable;
101 }
102 
104 {
105  return mFilterModel->masterModel();
106 }
107 
108 bool QgsFeatureListModel::setDisplayExpression( const QString expression )
109 {
110  const QgsFields fields = mFilterModel->layer()->dataProvider()->fields();
111 
112  QgsExpression* exp = new QgsExpression( expression );
113 
114  exp->prepare( fields );
115 
116  if ( exp->hasParserError() )
117  {
119  delete exp;
120  return false;
121  }
122 
123  delete mExpression;
124  mExpression = exp;
125 
126  emit( dataChanged( index( 0, 0 ), index( rowCount() - 1, 0 ) ) );
127  return true;
128 }
129 
131 {
132  return mParserErrorString;
133 }
134 
136 {
137  return mExpression->expression();
138 }
139 
140 bool QgsFeatureListModel::featureByIndex( const QModelIndex &index, QgsFeature &feat )
141 {
142  return mFilterModel->layerCache()->featureAtId( idxToFid( index ), feat );
143 }
144 
145 void QgsFeatureListModel::onBeginRemoveRows( const QModelIndex& parent, int first, int last )
146 {
147  beginRemoveRows( parent, first, last );
148 }
149 
150 void QgsFeatureListModel::onEndRemoveRows( const QModelIndex& parent, int first, int last )
151 {
152  Q_UNUSED( parent )
153  Q_UNUSED( first )
154  Q_UNUSED( last )
155  endRemoveRows();
156 }
157 
158 void QgsFeatureListModel::onBeginInsertRows( const QModelIndex& parent, int first, int last )
159 {
160  beginInsertRows( parent, first, last );
161 }
162 
163 void QgsFeatureListModel::onEndInsertRows( const QModelIndex& parent, int first, int last )
164 {
165  Q_UNUSED( parent )
166  Q_UNUSED( first )
167  Q_UNUSED( last )
168  endInsertRows();
169 }
170 
171 QModelIndex QgsFeatureListModel::mapToMaster( const QModelIndex &proxyIndex ) const
172 {
173  if ( !proxyIndex.isValid() )
174  return QModelIndex();
175 
176  return mFilterModel->mapToMaster( mFilterModel->index( proxyIndex.row(), proxyIndex.column() ) );
177 }
178 
179 QModelIndex QgsFeatureListModel::mapFromMaster( const QModelIndex &sourceIndex ) const
180 {
181  if ( !sourceIndex.isValid() )
182  return QModelIndex();
183 
184  return createIndex( mFilterModel->mapFromMaster( sourceIndex ).row(), 0 );
185 }
186 
187 QItemSelection QgsFeatureListModel::mapSelectionFromMaster( const QItemSelection& selection ) const
188 {
189  return mapSelectionFromSource( mFilterModel->mapSelectionFromSource( selection ) ) ;
190 }
191 
192 QItemSelection QgsFeatureListModel::mapSelectionToMaster( const QItemSelection& selection ) const
193 {
194  return mFilterModel->mapSelectionToSource( mapSelectionToSource( selection ) ) ;
195 }
196 
197 // Override some methods from QAbstractProxyModel, not that interesting
198 
199 QModelIndex QgsFeatureListModel::mapToSource( const QModelIndex &proxyIndex ) const
200 {
201  if ( !proxyIndex.isValid() )
202  return QModelIndex();
203 
204  return sourceModel()->index( proxyIndex.row(), proxyIndex.column() );
205 }
206 
207 QModelIndex QgsFeatureListModel::mapFromSource( const QModelIndex &sourceIndex ) const
208 {
209  if ( !sourceIndex.isValid() )
210  return QModelIndex();
211 
212  return createIndex( sourceIndex.row(), 0 );
213 }
214 
215 QModelIndex QgsFeatureListModel::index( int row, int column, const QModelIndex& parent ) const
216 {
217  Q_UNUSED( parent )
218  return createIndex( row, column );
219 }
220 
221 QModelIndex QgsFeatureListModel::parent( const QModelIndex& child ) const
222 {
223  Q_UNUSED( child )
224  return QModelIndex();
225 }
226 
227 int QgsFeatureListModel::columnCount( const QModelIndex&parent ) const
228 {
229  Q_UNUSED( parent )
230  return 1;
231 }
232 
233 int QgsFeatureListModel::rowCount( const QModelIndex& parent ) const
234 {
235  Q_UNUSED( parent )
236  return sourceModel()->rowCount();
237 }
238 
240 {
241  return mapFromMaster( masterModel()->idToIndex( fid ) );
242 }
243 
245 {
246  return QModelIndexList() << fidToIndex( fid );
247 }