@@ -228,8 +228,33 @@ void QgsQueryResultWidget::showCellContextMenu( QPoint point )
228
228
229
229
menu->addAction ( QgsApplication::getThemeIcon ( " mActionEditCopy.svg" ), tr ( " Copy" ), this , [ = ]
230
230
{
231
- const QString text = mModel ->data ( modelIndex, Qt::DisplayRole ).toString ();
232
- QApplication::clipboard ()->setText ( text );
231
+ const QModelIndexList selection = mQueryResultsTableView ->selectionModel ()->selectedIndexes ();
232
+ int minRow = -1 ;
233
+ int maxRow = -1 ;
234
+ int minCol = -1 ;
235
+ int maxCol = -1 ;
236
+ for ( const QModelIndex &index : selection )
237
+ {
238
+ if ( minRow == -1 || index.row () < minRow )
239
+ minRow = index.row ();
240
+ if ( maxRow == -1 || index.row () > maxRow )
241
+ maxRow = index.row ();
242
+ if ( minCol == -1 || index.column () < minCol )
243
+ minCol = index.column ();
244
+ if ( maxCol == -1 || index.column () > maxCol )
245
+ maxCol = index.column ();
246
+ }
247
+
248
+ if ( minRow == maxRow && minCol == maxCol )
249
+ {
250
+ // copy only one cell
251
+ const QString text = mModel ->data ( modelIndex, Qt::DisplayRole ).toString ();
252
+ QApplication::clipboard ()->setText ( text );
253
+ }
254
+ else
255
+ {
256
+ copyResults ( minRow, maxRow, minCol, maxCol );
257
+ }
233
258
}, QKeySequence::Copy );
234
259
235
260
menu->exec ( mQueryResultsTableView ->viewport ()->mapToGlobal ( point ) );
@@ -388,6 +413,63 @@ void QgsQueryResultWidget::tokensReady( const QStringList &tokens )
388
413
mSqlErrorText ->setExtraKeywords ( mSqlErrorText ->extraKeywords () + tokens );
389
414
}
390
415
416
+ void QgsQueryResultWidget::copyResults ()
417
+ {
418
+ const int rowCount = mModel ->rowCount ( QModelIndex () );
419
+ const int columnCount = mModel ->columnCount ( QModelIndex () );
420
+ copyResults ( 0 , rowCount - 1 , 0 , columnCount - 1 );
421
+ }
422
+
423
+ void QgsQueryResultWidget::copyResults ( int fromRow, int toRow, int fromColumn, int toColumn )
424
+ {
425
+ QStringList rowStrings;
426
+ QStringList columnStrings;
427
+
428
+ const int rowCount = mModel ->rowCount ( QModelIndex () );
429
+ const int columnCount = mModel ->columnCount ( QModelIndex () );
430
+
431
+ toRow = std::min ( toRow, rowCount - 1 );
432
+ toColumn = std::min ( toColumn, columnCount - 1 );
433
+
434
+ rowStrings.reserve ( toRow - fromRow );
435
+
436
+ // add titles first
437
+ for ( int col = fromColumn; col <= toColumn; col++ )
438
+ {
439
+ columnStrings += mModel ->headerData ( col, Qt::Horizontal, Qt::DisplayRole ).toString ();
440
+ }
441
+ rowStrings += columnStrings.join ( QLatin1Char ( ' \t ' ) );
442
+ columnStrings.clear ();
443
+
444
+ for ( int row = fromRow; row <= toRow; row++ )
445
+ {
446
+ for ( int col = fromColumn; col <= toColumn; col++ )
447
+ {
448
+ columnStrings += mModel ->data ( mModel ->index ( row, col ), Qt::DisplayRole ).toString ();
449
+ }
450
+ rowStrings += columnStrings.join ( QLatin1Char ( ' \t ' ) );
451
+ columnStrings.clear ();
452
+ }
453
+
454
+ if ( !rowStrings.isEmpty () )
455
+ {
456
+ const QString text = rowStrings.join ( QLatin1Char ( ' \n ' ) );
457
+ QString html = QStringLiteral ( " <!DOCTYPE HTML PUBLIC \" -//W3C//DTD HTML 4.0 Transitional//EN\" ><html><head><meta http-equiv=\" content-type\" content=\" text/html; charset=utf-8\" /></head><body><table border=\" 1\" ><tr><td>%1</td></tr></table></body></html>" ).arg ( text );
458
+ html.replace ( QLatin1String ( " \t " ), QLatin1String ( " </td><td>" ) ).replace ( QLatin1String ( " \n " ), QLatin1String ( " </td></tr><tr><td>" ) );
459
+
460
+ QMimeData *mdata = new QMimeData ();
461
+ mdata->setData ( QStringLiteral ( " text/html" ), html.toUtf8 () );
462
+ if ( !text.isEmpty () )
463
+ {
464
+ mdata->setText ( text );
465
+ }
466
+ // Transfers ownership to the clipboard object
467
+ #ifdef Q_OS_LINUX
468
+ QApplication::clipboard ()->setMimeData ( mdata, QClipboard::Selection );
469
+ #endif
470
+ QApplication::clipboard ()->setMimeData ( mdata, QClipboard::Clipboard );
471
+ }
472
+ }
391
473
392
474
QgsAbstractDatabaseProviderConnection::SqlVectorLayerOptions QgsQueryResultWidget::sqlVectorLayerOptions () const
393
475
{
0 commit comments