[QGIS Commit] r12104 - trunk/qgis/src/app/attributetable
svn_qgis at osgeo.org
svn_qgis at osgeo.org
Sat Nov 14 11:24:50 EST 2009
Author: wonder
Date: 2009-11-14 11:24:49 -0500 (Sat, 14 Nov 2009)
New Revision: 12104
Modified:
trunk/qgis/src/app/attributetable/qgsattributetabledialog.cpp
trunk/qgis/src/app/attributetable/qgsattributetabledialog.h
trunk/qgis/src/app/attributetable/qgsattributetableview.cpp
trunk/qgis/src/app/attributetable/qgsattributetableview.h
Log:
Applied patch from ticket #1927.
It adds some improvements to selection handling in attribute table (see the ticket for details).
Contributed by German Carillo - thanks!
Modified: trunk/qgis/src/app/attributetable/qgsattributetabledialog.cpp
===================================================================
--- trunk/qgis/src/app/attributetable/qgsattributetabledialog.cpp 2009-11-14 11:21:34 UTC (rev 12103)
+++ trunk/qgis/src/app/attributetable/qgsattributetabledialog.cpp 2009-11-14 16:24:49 UTC (rev 12104)
@@ -115,6 +115,7 @@
connect( mLayer, SIGNAL( selectionChanged() ), this, SLOT( updateSelectionFromLayer() ) );
connect( mLayer, SIGNAL( layerDeleted() ), this, SLOT( close() ) );
connect( mView->verticalHeader(), SIGNAL( sectionClicked( int ) ), this, SLOT( updateRowSelection( int ) ) );
+ connect( mView->verticalHeader(), SIGNAL( sectionPressed( int ) ), this, SLOT( updateRowPressed( int ) ) );
connect( mModel, SIGNAL( modelChanged() ), this, SLOT( updateSelection() ) );
mLastClickedHeaderIndex = 0;
@@ -262,8 +263,6 @@
void QgsAttributeTableDialog::updateSelection()
{
QModelIndex index;
- mView->setSelectionMode( QAbstractItemView::MultiSelection );
-
QItemSelection selection;
QgsFeatureIds::Iterator it = mSelectedFeatures.begin();
@@ -277,7 +276,6 @@
mSelectionModel->select( selection, QItemSelectionModel::ClearAndSelect );// | QItemSelectionModel::Columns);
mView->setSelectionModel( mSelectionModel );
- mView->setSelectionMode( QAbstractItemView::NoSelection );
/*for (int i = 0; i < mModel->rowCount(); ++i)
{
@@ -288,127 +286,200 @@
*/
}
+void QgsAttributeTableDialog::updateRowPressed( int index )
+{
+ mView->setSelectionMode( QAbstractItemView::ExtendedSelection );
+ mIndexPressed = index;
+}
+
void QgsAttributeTableDialog::updateRowSelection( int index )
{
- // map index to filter model
- //index = mFilterModel->mapFromSource(mModel->index(index, 0)).row();
+ bool bDrag;
- if ( mView->shiftPressed() )
+ if ( mIndexPressed == index )
+ bDrag = false;
+ else
+ bDrag = true;
+
+ QString key = "";
+ if ( QApplication::keyboardModifiers() == Qt::ControlModifier )
+ key = "Control";
+ else if ( QApplication::keyboardModifiers() == Qt::ShiftModifier )
+ key = "Shift";
+
+ int first, last;
+
+ if ( bDrag )
{
- QgsDebugMsg( "shift" );
- // get the first and last index of the rows to be selected/deselected
- int first, last;
- if ( index > mLastClickedHeaderIndex )
+ if ( mIndexPressed < index )
{
- first = mLastClickedHeaderIndex + 1;
- last = index;
+ first = mIndexPressed;
+ mLastClickedHeaderIndex = last = index;
}
- else if ( index == mLastClickedHeaderIndex )
- {
- // row was selected and now it is shift-clicked
- // ignore the shift and deselect the row
- first = last = index;
- }
else
{
- first = index;
- last = mLastClickedHeaderIndex - 1;
+ last = mIndexPressed;
+ mLastClickedHeaderIndex = first = index;
}
- // for all the rows update the selection, without starting a new selection
- if ( first <= last )
- updateRowSelection( first, last, false );
-
- mLastClickedHeaderIndex = last;
+ updateRowSelection( first, last, 3 );
+ mView->setSelectionMode( QAbstractItemView::NoSelection );
+ return;
}
- else if ( mView->ctrlPressed() )
+ else // No drag
{
- QgsDebugMsg( "ctrl" );
- // update the single row selection, without starting a new selection
- updateRowSelection( index, index, false );
+ if ( key == "Shift" )
+ {
+ QgsDebugMsg( "shift" );
+ // get the first and last index of the rows to be selected/deselected
+ first = last = 0;
- // the next shift would start from here
- mLastClickedHeaderIndex = index;
- }
- else
- {
- QgsDebugMsg( "ordinary click" );
- // update the single row selection, start a new selection if the row was not selected
- updateRowSelection( index, index, true );
+ if ( index > mLastClickedHeaderIndex )
+ {
+ first = mLastClickedHeaderIndex;
+ last = index;
+ }
+ else if ( index == mLastClickedHeaderIndex )
+ {
+ // row was selected and now it is shift-clicked
+ first = last = index;
+ }
+ else
+ {
+ first = index;
+ last = mLastClickedHeaderIndex;
+ }
- // the next shift would start from here
- mLastClickedHeaderIndex = index;
+ // for all the rows update the selection, without starting a new selection
+ if ( first <= last )
+ updateRowSelection( first, last, 1 );
+ }
+ else if ( key == "Control" )
+ {
+ QgsDebugMsg( "ctrl" );
+ // update the single row selection, without starting a new selection
+ updateRowSelection( index, index, 2 );
+
+ // the next shift would start from here
+ mLastClickedHeaderIndex = index;
+ }
+ else // Single click
+ {
+ // Start a new selection if the row was not selected
+ updateRowSelection( index, index, 0 );
+
+ // the next shift would start from here
+ mLastClickedHeaderIndex = index;
+ }
}
+ mView->setSelectionMode( QAbstractItemView::NoSelection );
}
-// fast row deselection needed
-void QgsAttributeTableDialog::updateRowSelection( int first, int last, bool startNewSelection )
+void QgsAttributeTableDialog::updateRowSelection( int first, int last, int clickType )
{
+ // clickType= 0:Single click, 1:Shift, 2:Ctrl, 3: Dragged click
disconnect( mLayer, SIGNAL( selectionChanged() ), this, SLOT( updateSelectionFromLayer() ) );
- //index = mFilterModel->mapFromSource(mModel->index(index, 0)).row();
// Id must be mapped to table/view row
QModelIndex index = mFilterModel->mapToSource( mFilterModel->index( first, 0 ) );
int fid = mModel->rowToId( index.row() );
bool wasSelected = mSelectedFeatures.contains( fid );
// new selection should be created
- if ( startNewSelection )
+ if ( clickType == 0 ) // Single click
{
- mView->clearSelection();
- mSelectedFeatures.clear();
+ if ( mSelectedFeatures.size() == 1 and wasSelected ) // One item selected
+ return // Click over a selected item doesn't do anything
- if ( wasSelected )
- {
- mLayer->removeSelection();
- connect( mLayer, SIGNAL( selectionChanged() ), this, SLOT( updateSelectionFromLayer() ) );
- return;
- }
-
- // set clicked row to current
mView->setCurrentIndex( mFilterModel->index( first, 0 ) );
- mView->setSelectionMode( QAbstractItemView::SingleSelection );
-
- //QModelIndex index = mFilterModel->mapFromSource(mModel->index(first, 0));
-
mView->selectRow( first );
- mView->setSelectionMode( QAbstractItemView::NoSelection );
+ mSelectedFeatures.clear();
mSelectedFeatures.insert( fid );
- //mLayer->setSelectedFeatures(mSelectedFeatures);
mLayer->removeSelection();
mLayer->select( fid );
- //mFilterModel->invalidate();
connect( mLayer, SIGNAL( selectionChanged() ), this, SLOT( updateSelectionFromLayer() ) );
return;
}
+ else if ( clickType == 1 ) // Shift
+ {
+ QgsFeatureIds newSelection;
- // existing selection should be updated
- for ( int i = first; i <= last; ++i )
- {
- if ( i > first )
+ for ( int i = first; i <= last; ++i )
{
- // Id must be mapped to table/view row
- index = mFilterModel->mapToSource( mFilterModel->index( i, 0 ) );
- fid = mModel->rowToId( index.row() );
- wasSelected = mSelectedFeatures.contains( fid );
+ if ( i >= first )
+ {
+ // Id must be mapped to table/view row
+ index = mFilterModel->mapToSource( mFilterModel->index( i, 0 ) );
+ fid = mModel->rowToId( index.row() );
+ }
+ newSelection.insert( fid );
}
+ // Remove items in mSelectedFeatures if they aren't in mNewSelection
+ QgsFeatureIds::Iterator it = mSelectedFeatures.begin();
+ while ( it != mSelectedFeatures.end() ) {
+ if ( !newSelection.contains( *it ) ) {
+ it = mSelectedFeatures.erase( it );
+ } else {
+ ++it;
+ }
+ }
+
+ // Append the other fids in range first-last to mSelectedFeatures
+ QgsFeatureIds::Iterator itNew = newSelection.begin();
+ for ( ; itNew != newSelection.end(); ++itNew )
+ {
+ if ( !mSelectedFeatures.contains( *itNew ) )
+ {
+ mSelectedFeatures.insert( *itNew );
+ }
+ }
+ }
+ else if ( clickType == 2 ) // Ctrl
+ {
+ // existing selection should be updated
if ( wasSelected )
mSelectedFeatures.remove( fid );
else
mSelectedFeatures.insert( fid );
}
- //mFilterModel->invalidate();
+ else if ( clickType == 3 ) // Dragged click
+ {
+ QgsFeatureIds newSelection;
- /*
- QItemSelection selection;
- QModelIndex leftUpIndex = mFilterModel->index(first, 0);
- QModelIndex rightBottomIndex = mFilterModel->index(last, mModel->columnCount() - 1);
- selection.append(QItemSelectionRange(leftUpIndex, rightBottomIndex));
- mSelectionModel->select(selection, QItemSelectionModel::Select);
- mView->setSelectionModel(mSelectionModel);
- */
+ for ( int i = first; i <= last; ++i )
+ {
+ if ( i >= first )
+ {
+ // Id must be mapped to table/view row
+ index = mFilterModel->mapToSource( mFilterModel->index( i, 0 ) );
+ fid = mModel->rowToId( index.row() );
+ }
+ newSelection.insert( fid );
+ }
+
+ // Remove items in mSelectedFeatures if they aren't in mNewSelection
+ QgsFeatureIds::Iterator it = mSelectedFeatures.begin();
+ while ( it != mSelectedFeatures.end() ) {
+ if ( !newSelection.contains( *it ) ) {
+ it = mSelectedFeatures.erase( it );
+ } else {
+ ++it;
+ }
+ }
+
+ // Append the other fids in range first-last to mSelectedFeatures
+ QgsFeatureIds::Iterator itNew = newSelection.begin();
+ for ( ; itNew != newSelection.end(); ++itNew )
+ {
+ if ( !mSelectedFeatures.contains( *itNew ) )
+ {
+ mSelectedFeatures.insert( *itNew );
+ }
+ }
+ }
+
updateSelection();
mLayer->setSelectedFeatures( mSelectedFeatures );
connect( mLayer, SIGNAL( selectionChanged() ), this, SLOT( updateSelectionFromLayer() ) );
Modified: trunk/qgis/src/app/attributetable/qgsattributetabledialog.h
===================================================================
--- trunk/qgis/src/app/attributetable/qgsattributetabledialog.h 2009-11-14 11:21:34 UTC (rev 12103)
+++ trunk/qgis/src/app/attributetable/qgsattributetabledialog.h 2009-11-14 16:24:49 UTC (rev 12104)
@@ -87,12 +87,16 @@
*/
void updateRowSelection( int index );
/**
+ * Updates the index pressed
+ */
+ void updateRowPressed( int index );
+ /**
* Updates selection of specifed rows
* @param first first row
* @param last last row
- * @param startNewSelection if true, then new selection is started
+ * @param clickType 0:Single click, 1:Shift, 2:Ctrl, 3:dragged click
*/
- void updateRowSelection( int first, int last, bool startNewSelection );
+ void updateRowSelection( int first, int last, int clickType );
/**
* Toggle showing of selected line only
@@ -183,6 +187,7 @@
QgsAttributeTableFilterModel *mFilterModel;
QgsVectorLayer *mLayer;
QgsFeatureIds mSelectedFeatures;
+ int mIndexPressed;
QItemSelectionModel* mSelectionModel;
int mLastClickedHeaderIndex;
Modified: trunk/qgis/src/app/attributetable/qgsattributetableview.cpp
===================================================================
--- trunk/qgis/src/app/attributetable/qgsattributetableview.cpp 2009-11-14 11:21:34 UTC (rev 12103)
+++ trunk/qgis/src/app/attributetable/qgsattributetableview.cpp 2009-11-14 16:24:49 UTC (rev 12104)
@@ -42,8 +42,6 @@
setSelectionMode( QAbstractItemView::NoSelection );
setSortingEnabled( true );
- mShiftPressed = false;
- mCtrlPressed = false;
}
void QgsAttributeTableView::setLayer( QgsVectorLayer* layer )
@@ -73,25 +71,3 @@
QSettings settings;
settings.setValue( "/BetterAttributeTable/geometry", QVariant( saveGeometry() ) );
}
-
-void QgsAttributeTableView::keyPressEvent( QKeyEvent *event )
-{
- // shift pressed
- if ( event->key() == Qt::Key_Shift )// && event->modifiers() & Qt::ShiftModifier)
- mShiftPressed = true;
- else if ( event->key() == Qt::Key_Control )
- mCtrlPressed = true;
- else
- QTableView::keyPressEvent( event );
-}
-
-void QgsAttributeTableView::keyReleaseEvent( QKeyEvent *event )
-{
- // workaround for some Qt bug
- if ( event->key() == Qt::Key_Shift || event->key() == -1 )
- mShiftPressed = false;
- else if ( event->key() == Qt::Key_Control )
- mCtrlPressed = false;
- else
- QTableView::keyReleaseEvent( event );
-}
Modified: trunk/qgis/src/app/attributetable/qgsattributetableview.h
===================================================================
--- trunk/qgis/src/app/attributetable/qgsattributetableview.h 2009-11-14 11:21:34 UTC (rev 12103)
+++ trunk/qgis/src/app/attributetable/qgsattributetableview.h 2009-11-14 16:24:49 UTC (rev 12104)
@@ -41,29 +41,8 @@
* @param event not used
*/
void closeEvent( QCloseEvent *event );
- /**
- * Handles Ctrl or Shift key press
- * @param event the key pressed
- */
- void keyPressEvent( QKeyEvent *event );
- /**
- * Handles Ctrl or Shift key release
- * @param event the key released
- */
- void keyReleaseEvent( QKeyEvent *event );
- /**
- * Returns true if shift was pressed
- */
- bool shiftPressed() { return mShiftPressed; }
- /**
- * Returns true if ctrl was pressed
- */
- bool ctrlPressed() { return mCtrlPressed; }
private:
- bool mShiftPressed;
- bool mCtrlPressed;
-
QgsAttributeTableModel* mModel;
QgsAttributeTableFilterModel* mFilterModel;
};
More information about the QGIS-commit
mailing list