Never quote cells when copying them to clipboard in text mode

This commit make sure that we never quote cells or change their contents
when copying to the text clipboard. This way the data can't be parsed
anymore without being ambigious but for these purposes we have the
internal buffer and the HTML clipboard. This makes sure that for simple
text copies (mainly that should be single cells) the data is never
changed.

This commit also uses the normal copy code for single cells unless they
are image cells. This makes sure that copying a single cell also uses
the internal buffer which in turn avoids problems when copying and
pasting single cells with line breaks in them.

See issue #1244.
This commit is contained in:
Martin Kleusberg
2018-09-28 18:53:03 +02:00
parent f4867e5c6d
commit 072ae15af0
2 changed files with 4 additions and 39 deletions

View File

@@ -347,7 +347,7 @@ void ExtendedTableWidget::copyMimeData(const QModelIndexList& fromIndices, QMime
// Clear internal copy-paste buffer
m_buffer.clear();
// If a single cell is selected, copy it to clipboard
// If a single cell is selected which contains an image, copy it to the clipboard
if (!inSQL && !withHeaders && indices.size() == 1) {
QImage img;
QVariant data = m->data(indices.first(), Qt::EditRole);
@@ -357,24 +357,10 @@ void ExtendedTableWidget::copyMimeData(const QModelIndexList& fromIndices, QMime
// If it's an image, copy the image data to the clipboard
mimeData->setImageData(img);
return;
} else {
// It it's not an image, check if it's an empty field
if (data.toByteArray().isEmpty())
{
// The field is either NULL or empty. Those are are handled via the internal copy-paste buffer
qApp->clipboard()->setText(QString()); // Calling clear() alone doesn't seem to work on all systems
qApp->clipboard()->clear();
m_buffer.push_back(QByteArrayList{data.toByteArray()});
return;
}
// The field isn't empty. Copy the text to the clipboard without quoting (for general plain text clipboard)
mimeData->setText(data.toByteArray());
return;
}
}
// If we got here, there are multiple selected cells, or copy with headers was requested.
// If we got here, a non-image cell was or multiple cells were selected, or copy with headers was requested.
// In this case, we copy selected data into internal copy-paste buffer and then
// we write a table both in HTML and text formats to the system clipboard.
@@ -432,7 +418,7 @@ void ExtendedTableWidget::copyMimeData(const QModelIndexList& fromIndices, QMime
sqlInsertStatement.append(", ");
}
result.append(escapeCopiedData(headerText));
result.append(headerText);
htmlResult.append(headerText);
sqlInsertStatement.append(sqlb::escapeIdentifier(headerText));
}
@@ -486,7 +472,7 @@ void ExtendedTableWidget::copyMimeData(const QModelIndexList& fromIndices, QMime
else
htmlResult.append(QString(text).toHtmlEscaped());
result.append(escapeCopiedData(text));
result.append(text);
sqlResult.append("'" + text.replace("'", "''") + "'");
} else
// Table cell data: binary. Save as BLOB literal in SQL
@@ -512,26 +498,6 @@ void ExtendedTableWidget::copy(const bool withHeaders, const bool inSQL )
qApp->clipboard()->setMimeData(mimeData);
}
QString ExtendedTableWidget::escapeCopiedData(const QByteArray& data) const
{
// Empty string is enquoted in plain text format, whilst NULL isn't
// We also quote the data when there are line breaks in the text, again for spreadsheet compatability.
// We also need to quote when there are tabs in the string (another option would be to replace the tabs by spaces, that's what
// LibreOffice seems to be doing here).
if(data.isNull())
return data;
QString text = data;
if(text.isEmpty() || text.contains('\n') || text.contains('\t') || text.contains('"'))
{
text.replace("\"", "\"\"");
return QString("\"%1\"").arg(text);
} else {
return text;
}
}
void ExtendedTableWidget::paste()
{
// Get list of selected items

View File

@@ -67,7 +67,6 @@ private:
void copyMimeData(const QModelIndexList& fromIndices, QMimeData* mimeData, const bool withHeaders, const bool inSQL);
void copy(const bool withHeaders, const bool inSQL);
void paste();
QString escapeCopiedData(const QByteArray& data) const;
void openPrintDialog();
void useAsFilter(const QString& filterOperator, bool binary = false);