QGIS API Documentation  2.7.0-Master
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules 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 
22 #include "qgsactionmenu.h"
25 #include "qgsattributetablemodel.h"
26 #include "qgsfeaturelistmodel.h"
28 #include "qgsfeaturelistview.h"
30 #include "qgslogger.h"
31 #include "qgsmapcanvas.h"
32 #include "qgsvectordataprovider.h"
33 #include "qgsvectorlayer.h"
35 
37  : QListView( parent )
38  , mModel( 0 )
39  , mCurrentEditSelectionModel( 0 )
40  , mFeatureSelectionModel( 0 )
41  , mItemDelegate( 0 )
42  , mEditSelectionDrag( false )
43 {
44  setSelectionMode( QAbstractItemView::ExtendedSelection );
45 }
46 
48 {
49  return mModel->layerCache();
50 }
51 
53 {
54  QListView::setModel( featureListModel );
55  mModel = featureListModel;
56 
57  delete mFeatureSelectionModel;
58  mFeatureSelectionModel = new QgsFeatureSelectionModel( featureListModel, featureListModel, new QgsVectorLayerSelectionManager( featureListModel->layerCache()->layer(), this ), this );
59  setSelectionModel( mFeatureSelectionModel );
60 
61  mCurrentEditSelectionModel = new QItemSelectionModel( mModel->masterModel(), this );
62 
63  if ( mItemDelegate && mItemDelegate->parent() == this )
64  {
65  delete mItemDelegate;
66  }
67 
68  mItemDelegate = new QgsFeatureListViewDelegate( mModel, this );
69  mItemDelegate->setEditSelectionModel( mCurrentEditSelectionModel );
70  setItemDelegate( mItemDelegate );
71 
72  mItemDelegate->setFeatureSelectionModel( mFeatureSelectionModel );
73  connect( mFeatureSelectionModel, SIGNAL( requestRepaint( QModelIndexList ) ), this, SLOT( repaintRequested( QModelIndexList ) ) );
74  connect( mFeatureSelectionModel, SIGNAL( requestRepaint() ), this, SLOT( repaintRequested() ) );
75 
76  connect( mCurrentEditSelectionModel, SIGNAL( selectionChanged( QItemSelection, QItemSelection ) ), SLOT( editSelectionChanged( QItemSelection, QItemSelection ) ) );
77 }
78 
79 bool QgsFeatureListView::setDisplayExpression( const QString expression )
80 {
81  if ( mModel->setDisplayExpression( expression ) )
82  {
83  emit displayExpressionChanged( expression );
84  return true;
85  }
86  else
87  {
88  return false;
89  }
90 }
91 
93 {
94  return mModel->displayExpression();
95 }
96 
98 {
99  return mModel->parserErrorString();
100 }
101 
103 {
104  QgsFeatureIds selection;
105  Q_FOREACH ( QModelIndex idx, mCurrentEditSelectionModel->selectedIndexes() )
106  {
107  selection << idx.data( QgsAttributeTableModel::FeatureIdRole ).value<QgsFeatureId>();
108  }
109  return selection;
110 }
111 
113 {
114  mItemDelegate->setCurrentFeatureEdited( state );
115  viewport()->update( visualRegionForSelection( mCurrentEditSelectionModel->selection() ) );
116 }
117 
118 void QgsFeatureListView::mousePressEvent( QMouseEvent *event )
119 {
120  if ( mModel )
121  {
122  QPoint pos = event->pos();
123 
124  QModelIndex index = indexAt( pos );
125 
126  if ( QgsFeatureListViewDelegate::EditElement == mItemDelegate->positionToElement( event->pos() ) )
127  {
128  mEditSelectionDrag = true;
129  setEditSelection( mModel->mapToMaster( index ), QItemSelectionModel::ClearAndSelect );
130  }
131  else
132  {
133  mFeatureSelectionModel->enableSync( false );
134  selectRow( index, true );
136  }
137  }
138  else
139  {
140  QgsDebugMsg( "No model assigned to this view" );
141  }
142 }
143 
144 void QgsFeatureListView::editSelectionChanged( QItemSelection deselected, QItemSelection selected )
145 {
146  if ( isVisible() && updatesEnabled() )
147  {
148  QItemSelection localDeselected = mModel->mapSelectionFromMaster( deselected );
149  QItemSelection localSelected = mModel->mapSelectionFromMaster( selected );
150  viewport()->update( visualRegionForSelection( localDeselected ) | visualRegionForSelection( localSelected ) );
151  }
152 
153  QItemSelection currentSelection = mCurrentEditSelectionModel->selection();
154  if ( currentSelection.size() == 1 )
155  {
156  QModelIndexList indexList = currentSelection.indexes();
157  if ( !indexList.isEmpty() )
158  {
159  QgsFeature feat;
160  mModel->featureByIndex( mModel->mapFromMaster( indexList.first() ), feat );
161 
162  emit currentEditSelectionChanged( feat );
163  }
164  }
165 }
166 
168 {
169  QItemSelection selection;
170  selection.append( QItemSelectionRange( mModel->index( 0, 0 ), mModel->index( mModel->rowCount() - 1, 0 ) ) );
171 
172  mFeatureSelectionModel->selectFeatures( selection, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows );
173 }
174 
176 {
177  QItemSelection selection;
178 
179  foreach ( QgsFeatureId fid, fids )
180  {
181  selection.append( QItemSelectionRange( mModel->mapToMaster( mModel->fidToIdx( fid ) ) ) );
182  }
183 
184  bool ok = true;
185  emit aboutToChangeEditSelection( ok );
186 
187  if ( ok )
188  mCurrentEditSelectionModel->select( selection, QItemSelectionModel::ClearAndSelect );
189 }
190 
191 void QgsFeatureListView::setEditSelection( const QModelIndex& index, QItemSelectionModel::SelectionFlags command )
192 {
193  bool ok = true;
194  emit aboutToChangeEditSelection( ok );
195 
196  if ( ok )
197  mCurrentEditSelectionModel->select( index, command );
198 }
199 
200 void QgsFeatureListView::repaintRequested( QModelIndexList indexes )
201 {
202  foreach ( const QModelIndex index, indexes )
203  {
204  update( index );
205  }
206 }
207 
209 {
210  setDirtyRegion( viewport()->rect() );
211 }
212 
219 void QgsFeatureListView::mouseMoveEvent( QMouseEvent *event )
220 {
221  QPoint pos = event->pos();
222 
223  QModelIndex index = indexAt( pos );
224 
225  if ( mEditSelectionDrag )
226  {
227  setEditSelection( mModel->mapToMaster( index ), QItemSelectionModel::ClearAndSelect );
228  }
229  else
230  {
231  selectRow( index, false );
232  }
233 }
234 
242 void QgsFeatureListView::mouseReleaseEvent( QMouseEvent *event )
243 {
244  Q_UNUSED( event );
245 
246  if ( mEditSelectionDrag )
247  {
248  mEditSelectionDrag = false;
249  }
250  else
251  {
252  mFeatureSelectionModel->enableSync( true );
253  }
254 }
255 
256 void QgsFeatureListView::keyPressEvent( QKeyEvent *event )
257 {
258  if ( Qt::Key_Up == event->key() || Qt::Key_Down == event->key() )
259  {
260  int currentRow = 0;
261  if ( 0 != mCurrentEditSelectionModel->selectedIndexes().count() )
262  {
263  QModelIndex localIndex = mModel->mapFromMaster( mCurrentEditSelectionModel->selectedIndexes().first() );
264  currentRow = localIndex.row();
265  }
266 
267  QModelIndex newLocalIndex;
268  QModelIndex newIndex;
269 
270  switch ( event->key() )
271  {
272  case Qt::Key_Up:
273  newLocalIndex = mModel->index( currentRow - 1, 0 );
274  newIndex = mModel->mapToMaster( newLocalIndex );
275  if ( newIndex.isValid() )
276  {
277  setEditSelection( newIndex, QItemSelectionModel::ClearAndSelect );
278  scrollTo( newLocalIndex );
279  }
280  break;
281 
282  case Qt::Key_Down:
283  newLocalIndex = mModel->index( currentRow + 1, 0 );
284  newIndex = mModel->mapToMaster( newLocalIndex );
285  if ( newIndex.isValid() )
286  {
287  setEditSelection( newIndex, QItemSelectionModel::ClearAndSelect );
288  scrollTo( newLocalIndex );
289  }
290  break;
291 
292  default:
293  break;
294  }
295  }
296  else
297  {
298  QListView::keyPressEvent( event );
299  }
300 }
301 
302 void QgsFeatureListView::contextMenuEvent( QContextMenuEvent *event )
303 {
304  QModelIndex index = indexAt( event->pos() );
305 
306  if ( index.isValid() )
307  {
308  QgsFeature feature = mModel->data( index, QgsFeatureListModel::FeatureRole ).value<QgsFeature>();
309 
310  QgsActionMenu menu( mModel->layerCache()->layer(), &feature, this );
311  menu.exec( event->globalPos() );
312  }
313 }
314 
315 void QgsFeatureListView::selectRow( const QModelIndex& index, bool anchor )
316 {
317  QItemSelectionModel::SelectionFlags command = selectionCommand( index );
318  int row = index.row();
319 
320  if ( anchor )
321  mRowAnchor = row;
322 
323  if ( selectionMode() != QListView::SingleSelection
324  && command.testFlag( QItemSelectionModel::Toggle ) )
325  {
326  if ( anchor )
327  mCtrlDragSelectionFlag = mFeatureSelectionModel->isSelected( index )
328  ? QItemSelectionModel::Deselect : QItemSelectionModel::Select;
329  command &= ~QItemSelectionModel::Toggle;
330  command |= mCtrlDragSelectionFlag;
331  if ( !anchor )
332  command |= QItemSelectionModel::Current;
333  }
334 
335  QModelIndex tl = model()->index( qMin( mRowAnchor, row ), 0 );
336  QModelIndex br = model()->index( qMax( mRowAnchor, row ), model()->columnCount() - 1 );
337 
338  mFeatureSelectionModel->selectFeatures( QItemSelection( tl, br ), command );
339 }
static unsigned index
virtual bool isSelected(QgsFeatureId fid)
Returns the selection status of a given feature id.
virtual QVariant data(const QModelIndex &index, int role) const
void setCurrentFeatureEdited(bool state)
Sets if the currently shown form has received any edit events so far.
virtual void mouseReleaseEvent(QMouseEvent *event)
#define QgsDebugMsg(str)
Definition: qgslogger.h:33
QSet< QgsFeatureId > QgsFeatureIds
Definition: qgsfeature.h:317
virtual QModelIndex mapToMaster(const QModelIndex &proxyIndex) const
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)
virtual void contextMenuEvent(QContextMenuEvent *event)
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)
virtual int rowCount(const QModelIndex &parent=QModelIndex()) const
void aboutToChangeEditSelection(bool &ok)
This class is a menu that is populated automatically with the actions defined for a given layer...
Definition: qgsactionmenu.h:30
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.
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)
virtual void selectAll()
Select all currently visible features.
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.