@@ -115,6 +115,7 @@ QgsAttributeTableDialog::QgsAttributeTableDialog( QgsVectorLayer *theLayer, QWid
115
115
connect ( mLayer , SIGNAL ( selectionChanged () ), this , SLOT ( updateSelectionFromLayer () ) );
116
116
connect ( mLayer , SIGNAL ( layerDeleted () ), this , SLOT ( close () ) );
117
117
connect ( mView ->verticalHeader (), SIGNAL ( sectionClicked ( int ) ), this , SLOT ( updateRowSelection ( int ) ) );
118
+ connect ( mView ->verticalHeader (), SIGNAL ( sectionPressed ( int ) ), this , SLOT ( updateRowPressed ( int ) ) );
118
119
connect ( mModel , SIGNAL ( modelChanged () ), this , SLOT ( updateSelection () ) );
119
120
120
121
mLastClickedHeaderIndex = 0 ;
@@ -262,8 +263,6 @@ int QgsAttributeTableDialog::columnBoxColumnId()
262
263
void QgsAttributeTableDialog::updateSelection ()
263
264
{
264
265
QModelIndex index ;
265
- mView ->setSelectionMode ( QAbstractItemView::MultiSelection );
266
-
267
266
QItemSelection selection;
268
267
269
268
QgsFeatureIds::Iterator it = mSelectedFeatures .begin ();
@@ -277,7 +276,6 @@ void QgsAttributeTableDialog::updateSelection()
277
276
278
277
mSelectionModel ->select ( selection, QItemSelectionModel::ClearAndSelect );// | QItemSelectionModel::Columns);
279
278
mView ->setSelectionModel ( mSelectionModel );
280
- mView ->setSelectionMode ( QAbstractItemView::NoSelection );
281
279
282
280
/* for (int i = 0; i < mModel->rowCount(); ++i)
283
281
{
@@ -288,127 +286,200 @@ void QgsAttributeTableDialog::updateSelection()
288
286
*/
289
287
}
290
288
289
+ void QgsAttributeTableDialog::updateRowPressed ( int index )
290
+ {
291
+ mView ->setSelectionMode ( QAbstractItemView::ExtendedSelection );
292
+ mIndexPressed = index ;
293
+ }
294
+
291
295
void QgsAttributeTableDialog::updateRowSelection ( int index )
292
296
{
293
- // map index to filter model
294
- // index = mFilterModel->mapFromSource(mModel->index(index, 0)).row();
297
+ bool bDrag;
295
298
296
- if ( mView ->shiftPressed () )
299
+ if ( mIndexPressed == index )
300
+ bDrag = false ;
301
+ else
302
+ bDrag = true ;
303
+
304
+ QString key = " " ;
305
+ if ( QApplication::keyboardModifiers () == Qt::ControlModifier )
306
+ key = " Control" ;
307
+ else if ( QApplication::keyboardModifiers () == Qt::ShiftModifier )
308
+ key = " Shift" ;
309
+
310
+ int first, last;
311
+
312
+ if ( bDrag )
297
313
{
298
- QgsDebugMsg ( " shift" );
299
- // get the first and last index of the rows to be selected/deselected
300
- int first, last;
301
- if ( index > mLastClickedHeaderIndex )
314
+ if ( mIndexPressed < index )
302
315
{
303
- first = mLastClickedHeaderIndex + 1 ;
304
- last = index ;
305
- }
306
- else if ( index == mLastClickedHeaderIndex )
307
- {
308
- // row was selected and now it is shift-clicked
309
- // ignore the shift and deselect the row
310
- first = last = index ;
316
+ first = mIndexPressed ;
317
+ mLastClickedHeaderIndex = last = index ;
311
318
}
312
319
else
313
320
{
314
- first = index ;
315
- last = mLastClickedHeaderIndex - 1 ;
321
+ last = mIndexPressed ;
322
+ mLastClickedHeaderIndex = first = index ;
316
323
}
317
324
318
- // for all the rows update the selection, without starting a new selection
319
- if ( first <= last )
320
- updateRowSelection ( first, last, false );
321
-
322
- mLastClickedHeaderIndex = last;
325
+ updateRowSelection ( first, last, 3 );
326
+ mView ->setSelectionMode ( QAbstractItemView::NoSelection );
327
+ return ;
323
328
}
324
- else if ( mView -> ctrlPressed () )
329
+ else // No drag
325
330
{
326
- QgsDebugMsg ( " ctrl" );
327
- // update the single row selection, without starting a new selection
328
- updateRowSelection ( index , index , false );
331
+ if ( key == " Shift" )
332
+ {
333
+ QgsDebugMsg ( " shift" );
334
+ // get the first and last index of the rows to be selected/deselected
335
+ first = last = 0 ;
329
336
330
- // the next shift would start from here
331
- mLastClickedHeaderIndex = index ;
332
- }
333
- else
334
- {
335
- QgsDebugMsg ( " ordinary click" );
336
- // update the single row selection, start a new selection if the row was not selected
337
- updateRowSelection ( index , index , true );
337
+ if ( index > mLastClickedHeaderIndex )
338
+ {
339
+ first = mLastClickedHeaderIndex ;
340
+ last = index ;
341
+ }
342
+ else if ( index == mLastClickedHeaderIndex )
343
+ {
344
+ // row was selected and now it is shift-clicked
345
+ first = last = index ;
346
+ }
347
+ else
348
+ {
349
+ first = index ;
350
+ last = mLastClickedHeaderIndex ;
351
+ }
338
352
339
- // the next shift would start from here
340
- mLastClickedHeaderIndex = index ;
353
+ // for all the rows update the selection, without starting a new selection
354
+ if ( first <= last )
355
+ updateRowSelection ( first, last, 1 );
356
+ }
357
+ else if ( key == " Control" )
358
+ {
359
+ QgsDebugMsg ( " ctrl" );
360
+ // update the single row selection, without starting a new selection
361
+ updateRowSelection ( index , index , 2 );
362
+
363
+ // the next shift would start from here
364
+ mLastClickedHeaderIndex = index ;
365
+ }
366
+ else // Single click
367
+ {
368
+ // Start a new selection if the row was not selected
369
+ updateRowSelection ( index , index , 0 );
370
+
371
+ // the next shift would start from here
372
+ mLastClickedHeaderIndex = index ;
373
+ }
341
374
}
375
+ mView ->setSelectionMode ( QAbstractItemView::NoSelection );
342
376
}
343
377
344
- // fast row deselection needed
345
- void QgsAttributeTableDialog::updateRowSelection ( int first, int last, bool startNewSelection )
378
+ void QgsAttributeTableDialog::updateRowSelection ( int first, int last, int clickType )
346
379
{
380
+ // clickType= 0:Single click, 1:Shift, 2:Ctrl, 3: Dragged click
347
381
disconnect ( mLayer , SIGNAL ( selectionChanged () ), this , SLOT ( updateSelectionFromLayer () ) );
348
382
349
- // index = mFilterModel->mapFromSource(mModel->index(index, 0)).row();
350
383
// Id must be mapped to table/view row
351
384
QModelIndex index = mFilterModel ->mapToSource ( mFilterModel ->index ( first, 0 ) );
352
385
int fid = mModel ->rowToId ( index .row () );
353
386
bool wasSelected = mSelectedFeatures .contains ( fid );
354
387
355
388
// new selection should be created
356
- if ( startNewSelection )
389
+ if ( clickType == 0 ) // Single click
357
390
{
358
- mView ->clearSelection ();
359
- mSelectedFeatures .clear ();
360
-
361
- if ( wasSelected )
362
- {
363
- mLayer ->removeSelection ();
364
- connect ( mLayer , SIGNAL ( selectionChanged () ), this , SLOT ( updateSelectionFromLayer () ) );
365
- return ;
366
- }
391
+ if ( mSelectedFeatures .size () == 1 and wasSelected ) // One item selected
392
+ return // Click over a selected item doesn't do anything
367
393
368
- // set clicked row to current
369
394
mView ->setCurrentIndex ( mFilterModel ->index ( first, 0 ) );
370
- mView ->setSelectionMode ( QAbstractItemView::SingleSelection );
371
-
372
- // QModelIndex index = mFilterModel->mapFromSource(mModel->index(first, 0));
373
-
374
395
mView ->selectRow ( first );
375
- mView ->setSelectionMode ( QAbstractItemView::NoSelection );
376
396
397
+ mSelectedFeatures .clear ();
377
398
mSelectedFeatures .insert ( fid );
378
- // mLayer->setSelectedFeatures(mSelectedFeatures);
379
399
mLayer ->removeSelection ();
380
400
mLayer ->select ( fid );
381
- // mFilterModel->invalidate();
382
401
connect ( mLayer , SIGNAL ( selectionChanged () ), this , SLOT ( updateSelectionFromLayer () ) );
383
402
return ;
384
403
}
385
-
386
- // existing selection should be updated
387
- for ( int i = first; i <= last; ++i )
404
+ else if ( clickType == 1 ) // Shift
388
405
{
389
- if ( i > first )
406
+ QgsFeatureIds newSelection;
407
+
408
+ for ( int i = first; i <= last; ++i )
390
409
{
391
- // Id must be mapped to table/view row
392
- index = mFilterModel ->mapToSource ( mFilterModel ->index ( i, 0 ) );
393
- fid = mModel ->rowToId ( index .row () );
394
- wasSelected = mSelectedFeatures .contains ( fid );
410
+ if ( i >= first )
411
+ {
412
+ // Id must be mapped to table/view row
413
+ index = mFilterModel ->mapToSource ( mFilterModel ->index ( i, 0 ) );
414
+ fid = mModel ->rowToId ( index .row () );
415
+ }
416
+ newSelection.insert ( fid );
395
417
}
396
418
419
+ // Remove items in mSelectedFeatures if they aren't in mNewSelection
420
+ QgsFeatureIds::Iterator it = mSelectedFeatures .begin ();
421
+ while ( it != mSelectedFeatures .end () ) {
422
+ if ( !newSelection.contains ( *it ) ) {
423
+ it = mSelectedFeatures .erase ( it );
424
+ } else {
425
+ ++it;
426
+ }
427
+ }
428
+
429
+ // Append the other fids in range first-last to mSelectedFeatures
430
+ QgsFeatureIds::Iterator itNew = newSelection.begin ();
431
+ for ( ; itNew != newSelection.end (); ++itNew )
432
+ {
433
+ if ( !mSelectedFeatures .contains ( *itNew ) )
434
+ {
435
+ mSelectedFeatures .insert ( *itNew );
436
+ }
437
+ }
438
+ }
439
+ else if ( clickType == 2 ) // Ctrl
440
+ {
441
+ // existing selection should be updated
397
442
if ( wasSelected )
398
443
mSelectedFeatures .remove ( fid );
399
444
else
400
445
mSelectedFeatures .insert ( fid );
401
446
}
402
- // mFilterModel->invalidate();
447
+ else if ( clickType == 3 ) // Dragged click
448
+ {
449
+ QgsFeatureIds newSelection;
450
+
451
+ for ( int i = first; i <= last; ++i )
452
+ {
453
+ if ( i >= first )
454
+ {
455
+ // Id must be mapped to table/view row
456
+ index = mFilterModel ->mapToSource ( mFilterModel ->index ( i, 0 ) );
457
+ fid = mModel ->rowToId ( index .row () );
458
+ }
459
+ newSelection.insert ( fid );
460
+ }
461
+
462
+ // Remove items in mSelectedFeatures if they aren't in mNewSelection
463
+ QgsFeatureIds::Iterator it = mSelectedFeatures .begin ();
464
+ while ( it != mSelectedFeatures .end () ) {
465
+ if ( !newSelection.contains ( *it ) ) {
466
+ it = mSelectedFeatures .erase ( it );
467
+ } else {
468
+ ++it;
469
+ }
470
+ }
471
+
472
+ // Append the other fids in range first-last to mSelectedFeatures
473
+ QgsFeatureIds::Iterator itNew = newSelection.begin ();
474
+ for ( ; itNew != newSelection.end (); ++itNew )
475
+ {
476
+ if ( !mSelectedFeatures .contains ( *itNew ) )
477
+ {
478
+ mSelectedFeatures .insert ( *itNew );
479
+ }
480
+ }
481
+ }
403
482
404
- /*
405
- QItemSelection selection;
406
- QModelIndex leftUpIndex = mFilterModel->index(first, 0);
407
- QModelIndex rightBottomIndex = mFilterModel->index(last, mModel->columnCount() - 1);
408
- selection.append(QItemSelectionRange(leftUpIndex, rightBottomIndex));
409
- mSelectionModel->select(selection, QItemSelectionModel::Select);
410
- mView->setSelectionModel(mSelectionModel);
411
- */
412
483
updateSelection ();
413
484
mLayer ->setSelectedFeatures ( mSelectedFeatures );
414
485
connect ( mLayer , SIGNAL ( selectionChanged () ), this , SLOT ( updateSelectionFromLayer () ) );
0 commit comments