From e60e9ffc758f26aa7d9833552bb5d3e1d3d566b3 Mon Sep 17 00:00:00 2001 From: mgrojo Date: Sat, 18 Nov 2017 21:38:50 +0100 Subject: [PATCH] Clipboard improvements: HTML and avoid pasting image from LibreCalc Both "Copy" and "Copy with Headers" write in HTML and text format to the system clipboard, when the selection includes more than one cell. This lets the pasting application choose the most appropriate format. Images have now no precedence over text when requesting the clipboard content, so pasting from applications like LibreCalc, that set both formats in the clipboard, works as expected, instead of pasting an image of the copied text. Copying and pasting inside the DB4S should not be affected, since the application requests the text format and uses the internal buffer when necessary (binary data included). Related issue: #1058 --- src/ExtendedTableWidget.cpp | 59 +++++++++++++++++++++++++++---------- 1 file changed, 43 insertions(+), 16 deletions(-) diff --git a/src/ExtendedTableWidget.cpp b/src/ExtendedTableWidget.cpp index 8282c9c2..99cac0e6 100644 --- a/src/ExtendedTableWidget.cpp +++ b/src/ExtendedTableWidget.cpp @@ -6,6 +6,7 @@ #include #include +#include #include #include #include @@ -163,7 +164,7 @@ void ExtendedTableWidget::copy(const bool withHeaders) m_buffer.clear(); // If a single cell is selected, copy it to clipboard - if (indices.size() == 1) { + if (!withHeaders && indices.size() == 1) { QImage img; QVariant data = m->data(indices.first(), Qt::EditRole); @@ -183,8 +184,6 @@ void ExtendedTableWidget::copy(const bool withHeaders) if (text.contains('\n')) text = QString("\"%1\"").arg(text); - if (withHeaders) - text.prepend(model()->headerData(indices.front().column(), Qt::Horizontal, Qt::DisplayRole).toString() + "\r\n"); qApp->clipboard()->setText(text); return; } @@ -216,30 +215,52 @@ void ExtendedTableWidget::copy(const bool withHeaders) return; } + // Multiple cells case: write a table both in HTML and text formats to clipboard + QModelIndex first = indices.first(); QString result; + QString htmlResult = "
"; int currentRow = 0; + const QString fieldSepHtml = ""); } - for(const QModelIndex& index : indices) { - if (first == index) { /* first index */ } - else if (index.row() != currentRow) - result.append("\r\n"); - else - result.append("\t"); + // Table data rows + for(const QModelIndex& index : indices) { + // Separators + if (first == index) + htmlResult.append("
"; + const QString rowSepHtml = "
"; + const QString fieldSepText = "\t"; + const QString rowSepText = "\r\n"; + + // Table headers if (withHeaders) { + htmlResult.append("
"); int firstColumn = indices.front().column(); for(int i = firstColumn; i <= indices.back().column(); i++) { QString headerText = model()->headerData(i, Qt::Horizontal, Qt::DisplayRole).toString(); - if (i != firstColumn) - result.append("\t"); + if (i != firstColumn) { + result.append(fieldSepText); + htmlResult.append(""); + } result.append(QString("\"%1\"").arg(headerText)); + htmlResult.append(headerText); } - result.append("\r\n"); + result.append(rowSepText); + htmlResult.append("
"); + else if (index.row() != currentRow) { + result.append(rowSepText); + htmlResult.append(rowSepHtml); + } else { + result.append(fieldSepText); + htmlResult.append(fieldSepHtml); + } currentRow = index.row(); QVariant data = index.data(Qt::EditRole); + // Table cell data + htmlResult.append(data.toString().toHtmlEscaped()); // non-NULL data is enquoted, whilst NULL isn't if (!data.isNull()) { QString text = data.toString(); @@ -248,7 +269,11 @@ void ExtendedTableWidget::copy(const bool withHeaders) } } - qApp->clipboard()->setText(result); + QMimeData *mimeData = new QMimeData; + mimeData->setHtml(htmlResult + "
"); + mimeData->setText(result); + qApp->clipboard()->setMimeData(mimeData); + } void ExtendedTableWidget::paste() @@ -263,9 +288,11 @@ void ExtendedTableWidget::paste() SqliteTableModel* m = qobject_cast(model()); - // If clipboard contains image - just insert it - QImage img = qApp->clipboard()->image(); - if (!img.isNull()) { + // If clipboard contains image and not text - just insert the image + const QMimeData* mimeClipboard = qApp->clipboard()->mimeData(); + + if (mimeClipboard->hasImage() && !mimeClipboard->hasText()) { + QImage img = qApp->clipboard()->image(); QByteArray ba; QBuffer buffer(&ba); buffer.open(QIODevice::WriteOnly);