void QgsFeatureListView::selectRow( const QModelIndex &index, bool anchor ) { QItemSelectionModel::SelectionFlags command = selectionCommand( index ); int row = index.row(); if ( anchor ) mRowAnchor = row; if ( selectionMode() != QListView::SingleSelection && command.testFlag( QItemSelectionModel::Toggle ) ) { if ( anchor ) mCtrlDragSelectionFlag = mFeatureSelectionModel->isSelected( index ) ? QItemSelectionModel::Deselect : QItemSelectionModel::Select; command &= ~QItemSelectionModel::Toggle; command |= mCtrlDragSelectionFlag; if ( !anchor ) command |= QItemSelectionModel::Current; } QModelIndex tl = model()->index( std::min( mRowAnchor, row ), 0 ); QModelIndex br = model()->index( std::max( mRowAnchor, row ), model()->columnCount() - 1 ); mFeatureSelectionModel->selectFeatures( QItemSelection( tl, br ), command ); }
void QgsFeatureSelectionModel::selectFeatures( const QItemSelection &selection, QItemSelectionModel::SelectionFlags command ) { QgsFeatureIds ids; foreach ( const QModelIndex index, selection.indexes() ) { QgsFeatureId id = index.model()->data( index, QgsAttributeTableModel::FeatureIdRole ).toInt(); ids << id; } disconnect( mLayer, SIGNAL( selectionChanged( QgsFeatureIds, QgsFeatureIds, bool ) ), this, SLOT( layerSelectionChanged( QgsFeatureIds, QgsFeatureIds, bool ) ) ); if ( command.testFlag( QItemSelectionModel::ClearAndSelect ) ) { if ( !mSyncEnabled ) { mClearAndSelectBuffer = true; foreach ( QgsFeatureId id, ids ) { if ( !mDeselectedBuffer.remove( id ) ) { mSelectedBuffer.insert( id ); } } } else {
void QgsFeatureSelectionModel::selectFeatures( const QItemSelection &selection, const QItemSelectionModel::SelectionFlags& command ) { QgsFeatureIds ids; QgsDebugMsg( QString( "Index count: %1" ).arg( selection.indexes().size() ) ); Q_FOREACH ( const QModelIndex& index, selection.indexes() ) { QgsFeatureId id = index.model()->data( index, QgsAttributeTableModel::FeatureIdRole ).toLongLong(); ids << id; } disconnect( mFeatureSelectionManager, SIGNAL( selectionChanged( QgsFeatureIds, QgsFeatureIds, bool ) ), this, SLOT( layerSelectionChanged( QgsFeatureIds, QgsFeatureIds, bool ) ) ); if ( command.testFlag( QItemSelectionModel::ClearAndSelect ) ) { if ( !mSyncEnabled ) { mClearAndSelectBuffer = true; Q_FOREACH ( QgsFeatureId id, ids ) { if ( !mDeselectedBuffer.remove( id ) ) { mSelectedBuffer.insert( id ); } } } else {
void AMActionHistoryTreeView3::mousePressEvent(QMouseEvent *event){ // Ignore mouse clicks if the cursor shows forbidden if(shiftKeyDown_ && hasOverriddenShiftCursor_){ event->ignore(); } // Actually handling valid shift-clicks else if(shiftKeyDown_){ AMActionHistoryModel3 *historyModel = qobject_cast<AMActionHistoryModel3*>(model()); QModelIndex index = indexAt(event->pos()); // We can ignore: bad models, invalid indexes, not enabled indexes, and not selectable indexes if(!historyModel || !index.isValid() || !index.flags().testFlag(Qt::ItemIsEnabled) || !index.flags().testFlag(Qt::ItemIsSelectable)) event->ignore(); // Grab current selection from model and the indices between the shift click QItemSelection currentSelection = selectionModel()->selection(); QItemSelection newSelection = historyModel->indicesBetween(index, lastClickedIndex_); // Call the selectionCommand function and merge the current and new selections QItemSelectionModel::SelectionFlags command = selectionCommand(index, event); currentSelection.merge(newSelection, command); // Clear the selection and select the combined list selectionModel()->clearSelection(); selectionModel()->select(currentSelection, command); // Grab the list indices between the shift click so we can apply the right parentSelected states to them QModelIndexList interiorIndices = newSelection.indexes(); // We only care about lists that have interior elements, the indicesBetween call returns the ends as well if(interiorIndices.count() >= 2){ // Grab the clear flag for the signal emitted below bool clearFlag = command.testFlag(QItemSelectionModel::Clear); // Not sure if the indices are ordered correctly, so figure out the min and max to remove them (they should be the ends we don't care about) QModelIndex minRowIndex = interiorIndices.at(0); int minRowValue = minRowIndex.row(); QModelIndex maxRowIndex = interiorIndices.at(1); int maxRowValue = maxRowIndex.row(); for(int x = 0; x < interiorIndices.count(); x++){ if(interiorIndices.at(x).row() < minRowValue){ minRowIndex = interiorIndices.at(x); minRowValue = minRowIndex.row(); } if(interiorIndices.at(x).row() > maxRowValue){ maxRowIndex = interiorIndices.at(x); maxRowValue = maxRowIndex.row(); } } // Remove both ends interiorIndices.removeOne(maxRowIndex); interiorIndices.removeOne(minRowIndex); // For all interior indices emulate a click by emitting the actuallySelectedByClicking signal ... then the regular chain of events can happen to parentSelect the children for(int x = 0; x < interiorIndices.count(); x++) emit actuallySelectedByClicking(interiorIndices.at(x), clearFlag); } // Accept the event event->accept(); } // Ignore mouse clicks if the cursor shows forbidden else if(controlKeyDown_ && hasOverriddenControlCursor_){ event->ignore(); } // Falls through, call the parent class else QTreeView::mousePressEvent(event); }