QGIS API Documentation  2.4.0-Chugiak
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
qgsfeaturelistview.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  QgsAttributeTableView.cpp
3  --------------------------------------
4  Date : Feb 2009
5  Copyright : (C) 2009 Vita Cizek
6  Email : weetya (at) gmail.com
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 
16 #include <QHeaderView>
17 #include <QKeyEvent>
18 #include <QMenu>
19 #include <QSet>
20 #include <QSettings>
21 
24 #include "qgsattributetablemodel.h"
25 #include "qgsfeaturelistmodel.h"
27 #include "qgsfeaturelistview.h"
29 #include "qgslogger.h"
30 #include "qgsmapcanvas.h"
31 #include "qgsvectordataprovider.h"
32 #include "qgsvectorlayer.h"
34 
36  : QListView( parent )
37  , mCurrentEditSelectionModel( NULL )
38  , mFeatureSelectionModel( NULL )
39  , mItemDelegate( NULL )
40  , mEditSelectionDrag( false )
41 {
42  setSelectionMode( QAbstractItemView::ExtendedSelection );
43 }
44 
46 {
47  return mModel->layerCache();
48 }
49 
51 {
52  QListView::setModel( featureListModel );
54 
56  mFeatureSelectionModel = new QgsFeatureSelectionModel( featureListModel, featureListModel, new QgsVectorLayerSelectionManager( featureListModel->layerCache()->layer(), this ), this );
57  setSelectionModel( mFeatureSelectionModel );
58 
59  mCurrentEditSelectionModel = new QItemSelectionModel( mModel->masterModel(), this );
60 
61  if ( mItemDelegate && mItemDelegate->parent() == this )
62  {
63  delete mItemDelegate;
64  }
65 
68  setItemDelegate( mItemDelegate );
69 
71  connect( mFeatureSelectionModel, SIGNAL( requestRepaint( QModelIndexList ) ), this, SLOT( repaintRequested( QModelIndexList ) ) );
72  connect( mFeatureSelectionModel, SIGNAL( requestRepaint() ), this, SLOT( repaintRequested() ) );
73 
74  connect( mCurrentEditSelectionModel, SIGNAL( selectionChanged( QItemSelection, QItemSelection ) ), SLOT( editSelectionChanged( QItemSelection, QItemSelection ) ) );
75 }
76 
77 bool QgsFeatureListView::setDisplayExpression( const QString expression )
78 {
79  if ( mModel->setDisplayExpression( expression ) )
80  {
81  emit displayExpressionChanged( expression );
82  return true;
83  }
84  else
85  {
86  return false;
87  }
88 }
89 
91 {
92  return mModel->displayExpression();
93 }
94 
96 {
97  return mModel->parserErrorString();
98 }
99 
101 {
102  QgsFeatureIds selection;
103  Q_FOREACH( QModelIndex idx, mCurrentEditSelectionModel->selectedIndexes() )
104  {
105  selection << idx.data( QgsAttributeTableModel::FeatureIdRole ).value<QgsFeatureId>();
106  }
107  return selection;
108 }
109 
111 {
113  viewport()->update( visualRegionForSelection( mCurrentEditSelectionModel->selection() ) );
114 }
115 
116 void QgsFeatureListView::mousePressEvent( QMouseEvent *event )
117 {
118  QPoint pos = event->pos();
119 
120  QModelIndex index = indexAt( pos );
121 
123  {
124  mEditSelectionDrag = true;
125  setEditSelection( mModel->mapToMaster( index ), QItemSelectionModel::ClearAndSelect );
126  }
127  else
128  {
130  selectRow( index, true );
132  }
133 }
134 
135 void QgsFeatureListView::editSelectionChanged( QItemSelection deselected, QItemSelection selected )
136 {
137  if ( isVisible() && updatesEnabled() )
138  {
139  QItemSelection localDeselected = mModel->mapSelectionFromMaster( deselected );
140  QItemSelection localSelected = mModel->mapSelectionFromMaster( selected );
141  viewport()->update( visualRegionForSelection( localDeselected ) | visualRegionForSelection( localSelected ) );
142  }
143 
144  QItemSelection currentSelection = mCurrentEditSelectionModel->selection();
145  if ( currentSelection.size() == 1 )
146  {
147  QModelIndexList indexList = currentSelection.indexes();
148  if ( !indexList.isEmpty() )
149  {
150  QgsFeature feat;
151  mModel->featureByIndex( mModel->mapFromMaster( indexList.first() ), feat );
152 
153  emit currentEditSelectionChanged( feat );
154  }
155  }
156 }
157 
159 {
160  QItemSelection selection;
161  selection.append( QItemSelectionRange( mModel->index( 0, 0 ), mModel->index( mModel->rowCount() - 1, 0 ) ) );
162 
163  mFeatureSelectionModel->selectFeatures( selection, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows );
164 }
165 
167 {
168  QItemSelection selection;
169 
170  foreach ( QgsFeatureId fid, fids )
171  {
172  selection.append( QItemSelectionRange( mModel->mapToMaster( mModel->fidToIdx( fid ) ) ) );
173  }
174 
175  bool ok = true;
176  emit aboutToChangeEditSelection( ok );
177 
178  if ( ok )
179  mCurrentEditSelectionModel->select( selection, QItemSelectionModel::ClearAndSelect );
180 }
181 
182 void QgsFeatureListView::setEditSelection( const QModelIndex& index, QItemSelectionModel::SelectionFlags command )
183 {
184  bool ok = true;
185  emit aboutToChangeEditSelection( ok );
186 
187  if ( ok )
188  mCurrentEditSelectionModel->select( index, command );
189 }
190 
191 void QgsFeatureListView::repaintRequested( QModelIndexList indexes )
192 {
193  foreach ( const QModelIndex index, indexes )
194  {
195  update( index );
196  }
197 }
198 
200 {
201  setDirtyRegion( viewport()->rect() );
202 }
203 
210 void QgsFeatureListView::mouseMoveEvent( QMouseEvent *event )
211 {
212  QPoint pos = event->pos();
213 
214  QModelIndex index = indexAt( pos );
215 
216  if ( mEditSelectionDrag )
217  {
218  setEditSelection( mModel->mapToMaster( index ), QItemSelectionModel::ClearAndSelect );
219  }
220  else
221  {
222  selectRow( index, false );
223  }
224 }
225 
233 void QgsFeatureListView::mouseReleaseEvent( QMouseEvent *event )
234 {
235  Q_UNUSED( event );
236 
237  if ( mEditSelectionDrag )
238  {
239  mEditSelectionDrag = false;
240  }
241  else
242  {
244  }
245 }
246 
247 void QgsFeatureListView::keyPressEvent( QKeyEvent *event )
248 {
249  if ( Qt::Key_Up == event->key() || Qt::Key_Down == event->key() )
250  {
251  int currentRow = 0;
252  if ( 0 != mCurrentEditSelectionModel->selectedIndexes().count() )
253  {
254  QModelIndex localIndex = mModel->mapFromMaster( mCurrentEditSelectionModel->selectedIndexes().first() );
255  currentRow = localIndex.row();
256  }
257 
258  QModelIndex newLocalIndex;
259  QModelIndex newIndex;
260 
261  switch ( event->key() )
262  {
263  case Qt::Key_Up:
264  newLocalIndex = mModel->index( currentRow - 1, 0 );
265  newIndex = mModel->mapToMaster( newLocalIndex );
266  if ( newIndex.isValid() )
267  {
268  setEditSelection( newIndex, QItemSelectionModel::ClearAndSelect );
269  scrollTo( newLocalIndex );
270  }
271  break;
272 
273  case Qt::Key_Down:
274  newLocalIndex = mModel->index( currentRow + 1, 0 );
275  newIndex = mModel->mapToMaster( newLocalIndex );
276  if ( newIndex.isValid() )
277  {
278  setEditSelection( newIndex, QItemSelectionModel::ClearAndSelect );
279  scrollTo( newLocalIndex );
280  }
281  break;
282 
283  default:
284  break;
285  }
286  }
287  else
288  {
289  QListView::keyPressEvent( event );
290  }
291 }
292 
293 void QgsFeatureListView::selectRow( const QModelIndex& index, bool anchor )
294 {
295  QItemSelectionModel::SelectionFlags command = selectionCommand( index );
296  int row = index.row();
297 
298  if ( anchor )
299  mRowAnchor = row;
300 
301  if ( selectionMode() != QListView::SingleSelection
302  && command.testFlag( QItemSelectionModel::Toggle ) )
303  {
304  if ( anchor )
306  ? QItemSelectionModel::Deselect : QItemSelectionModel::Select;
307  command &= ~QItemSelectionModel::Toggle;
308  command |= mCtrlDragSelectionFlag;
309  if ( !anchor )
310  command |= QItemSelectionModel::Current;
311  }
312 
313  QModelIndex tl = model()->index( qMin( mRowAnchor, row ), 0 );
314  QModelIndex br = model()->index( qMax( mRowAnchor, row ), model()->columnCount() - 1 );
315 
316  mFeatureSelectionModel->selectFeatures( QItemSelection( tl, br ), command );
317 }
QgsFeatureListViewDelegate * mItemDelegate
static unsigned index
virtual bool isSelected(QgsFeatureId fid)
Returns the selection status of a given feature id.
void setCurrentFeatureEdited(bool state)
Sets if the currently shown form has received any edit events so far.
virtual void mouseReleaseEvent(QMouseEvent *event)
QSet< QgsFeatureId > QgsFeatureIds
Definition: qgsfeature.h:325
virtual QModelIndex mapToMaster(const QModelIndex &proxyIndex) const
QgsFeatureListModel * mModel
bool featureByIndex(const QModelIndex &index, QgsFeature &feat)
virtual QModelIndex mapFromMaster(const QModelIndex &sourceIndex) const
QgsVectorLayer * layer()
Returns the layer to which this cache belongs.
virtual QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:113
virtual void mousePressEvent(QMouseEvent *event)
const QString displayExpression() const
Returns the expression which is currently used to render the features.
void enableSync(bool enable)
Enables or disables synchronisation to the QgsVectorLayer When synchronisation is disabled...
QString parserErrorString()
Returns a detailed message about errors while parsing a QgsExpression.
Element positionToElement(const QPoint &pos)
QgsFeatureListView(QWidget *parent=0)
Creates a feature list view.
QgsFeatureListModel * featureListModel()
Get the featureListModel used by this view.
void setFeatureSelectionModel(QgsFeatureSelectionModel *featureSelectionModel)
bool setDisplayExpression(const QString expression)
virtual void mouseMoveEvent(QMouseEvent *event)
QItemSelectionModel * mCurrentEditSelectionModel
virtual int rowCount(const QModelIndex &parent=QModelIndex()) const
void aboutToChangeEditSelection(bool &ok)
virtual void selectFeatures(const QItemSelection &selection, SelectionFlags command)
Select features on this table.
QString parserErrorString()
Returns a detailed message about errors while parsing a QgsExpression.
QgsFeatureIds currentEditSelection()
Get the currentEditSelection.
QItemSelectionModel::SelectionFlags mCtrlDragSelectionFlag
QgsAttributeTableModel * masterModel()
void displayExpressionChanged(const QString expression)
Is emitted, whenever the display expression is successfully changed.
This class caches features of a given QgsVectorLayer.
void setEditSelection(const QgsFeatureIds &fids)
Set the feature(s) to be edited.
bool setDisplayExpression(const QString displayExpression)
The display expression is an expression used to render the fields into a single string which is displ...
virtual void keyPressEvent(QKeyEvent *event)
QgsFeatureSelectionModel * mFeatureSelectionModel
virtual void selectAll()
Select all currently visible features.
void selectRow(const QModelIndex &index, bool anchor)
void editSelectionChanged(QItemSelection deselected, QItemSelection selected)
qint64 QgsFeatureId
Definition: qgsfeature.h:30
QgsVectorLayerCache * layerCache()
QModelIndex fidToIdx(const QgsFeatureId fid) const
void setEditSelectionModel(QItemSelectionModel *editSelectionModel)
void currentEditSelectionChanged(QgsFeature &feat)
Is emitted, whenever the current edit selection has been changed.
virtual QItemSelection mapSelectionFromMaster(const QItemSelection &selection) const
virtual void setModel(QgsFeatureListModel *featureListModel)
Set the QgsFeatureListModel which is used to retrieve information.
QString displayExpression() const
QgsVectorLayerCache * layerCache()
Returns the layer cache.