QGIS API Documentation  2.2.0-Valmiera
 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 
110 void QgsFeatureListView::mousePressEvent( QMouseEvent *event )
111 {
112  QPoint pos = event->pos();
113 
114  QModelIndex index = indexAt( pos );
115 
117  {
118  mEditSelectionDrag = true;
119  mCurrentEditSelectionModel->select( mModel->mapToMaster( index ), QItemSelectionModel::ClearAndSelect );
120  }
121  else
122  {
124  selectRow( index, true );
126  }
127 }
128 
129 void QgsFeatureListView::editSelectionChanged( QItemSelection deselected, QItemSelection selected )
130 {
131  if ( isVisible() && updatesEnabled() )
132  {
133  QItemSelection localDeselected = mModel->mapSelectionFromMaster( deselected );
134  QItemSelection localSelected = mModel->mapSelectionFromMaster( selected );
135  viewport()->update( visualRegionForSelection( localDeselected ) | visualRegionForSelection( localSelected ) );
136  }
137 
138  QItemSelection currentSelection = mCurrentEditSelectionModel->selection();
139  if ( currentSelection.size() == 1 )
140  {
141  QgsFeature feat;
142  mModel->featureByIndex( mModel->mapFromMaster( currentSelection.indexes().first() ), feat );
143 
144  emit currentEditSelectionChanged( feat );
145  }
146 }
147 
149 {
150  QItemSelection selection;
151  selection.append( QItemSelectionRange( mModel->index( 0, 0 ), mModel->index( mModel->rowCount() - 1, 0 ) ) );
152 
153  mFeatureSelectionModel->selectFeatures( selection, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows );
154 }
155 
157 {
158  QItemSelection selection;
159 
160  foreach ( QgsFeatureId fid, fids )
161  {
162  selection.append( QItemSelectionRange( mModel->mapToMaster( mModel->fidToIdx( fid ) ) ) );
163  }
164 
165  mCurrentEditSelectionModel->select( selection, QItemSelectionModel::ClearAndSelect );
166 }
167 
168 void QgsFeatureListView::repaintRequested( QModelIndexList indexes )
169 {
170  foreach ( const QModelIndex index, indexes )
171  {
172  update( index );
173  }
174 }
175 
177 {
178  setDirtyRegion( viewport()->rect() );
179 }
180 
187 void QgsFeatureListView::mouseMoveEvent( QMouseEvent *event )
188 {
189  QPoint pos = event->pos();
190 
191  QModelIndex index = indexAt( pos );
192 
193  if ( mEditSelectionDrag )
194  {
195  mCurrentEditSelectionModel->select( mModel->mapToMaster( index ), QItemSelectionModel::ClearAndSelect );
196  }
197  else
198  {
199  selectRow( index, false );
200  }
201 }
202 
210 void QgsFeatureListView::mouseReleaseEvent( QMouseEvent *event )
211 {
212  Q_UNUSED( event );
213 
214  if ( mEditSelectionDrag )
215  {
216  mEditSelectionDrag = false;
217  }
218  else
219  {
221  }
222 }
223 
224 void QgsFeatureListView::keyPressEvent( QKeyEvent *event )
225 {
226  if ( Qt::Key_Up == event->key() || Qt::Key_Down == event->key() )
227  {
228  int currentRow = 0;
229  if ( 0 != mCurrentEditSelectionModel->selectedIndexes().count() )
230  {
231  QModelIndex localIndex = mModel->mapFromMaster( mCurrentEditSelectionModel->selectedIndexes().first() );
232  currentRow = localIndex.row();
233  }
234 
235  QModelIndex newLocalIndex;
236  QModelIndex newIndex;
237 
238  switch ( event->key() )
239  {
240  case Qt::Key_Up:
241  newLocalIndex = mModel->index( currentRow - 1, 0 );
242  newIndex = mModel->mapToMaster( newLocalIndex );
243  if ( newIndex.isValid() )
244  {
245  mCurrentEditSelectionModel->select( newIndex, QItemSelectionModel::ClearAndSelect );
246  scrollTo( newLocalIndex );
247  }
248  break;
249 
250  case Qt::Key_Down:
251  newLocalIndex = mModel->index( currentRow + 1, 0 );
252  newIndex = mModel->mapToMaster( newLocalIndex );
253  if ( newIndex.isValid() )
254  {
255  mCurrentEditSelectionModel->select( newIndex, QItemSelectionModel::ClearAndSelect );
256  scrollTo( newLocalIndex );
257  }
258  break;
259 
260  default:
261  break;
262  }
263  }
264  else
265  {
266  QListView::keyPressEvent( event );
267  }
268 }
269 
270 void QgsFeatureListView::selectRow( const QModelIndex& index, bool anchor )
271 {
272  QItemSelectionModel::SelectionFlags command = selectionCommand( index );
273  int row = index.row();
274 
275  if ( anchor )
276  mRowAnchor = row;
277 
278  if ( selectionMode() != QListView::SingleSelection
279  && command.testFlag( QItemSelectionModel::Toggle ) )
280  {
281  if ( anchor )
283  ? QItemSelectionModel::Deselect : QItemSelectionModel::Select;
284  command &= ~QItemSelectionModel::Toggle;
285  command |= mCtrlDragSelectionFlag;
286  if ( !anchor )
287  command |= QItemSelectionModel::Current;
288  }
289 
290  QModelIndex tl = model()->index( qMin( mRowAnchor, row ), 0 );
291  QModelIndex br = model()->index( qMax( mRowAnchor, row ), model()->columnCount() - 1 );
292 
293  mFeatureSelectionModel->selectFeatures( QItemSelection( tl, br ), command );
294 }