Я разрабатываю приложение Qt для хранения всего, что проходит через буфер обмена, чтобы потом его можно было восстановить. Мой подход состоял в том, чтобы получить QMimeData от QApplication::clipboard()
и хранить его в QList<QMimeData *>
, Поскольку данные в буфере обмена изменчивы, я должен скопировать QMimeData, возвращенный QClipboard::mimeData()
,
Для QMimeData нет конструктора копирования, поэтому я решил, что скопировал бы его так:
const QMimeData * clipboardData = _clipboard->mimeData();
QMimeData * mimeCopy = new QMimeData();
foreach(const QString & format, clipboardData->formats())
mimeCopy->setData(format, clipboardData->data(format))
где _clipboard
это QApplication::clipboard()
,
Это работает относительно хорошо, за исключением некоторых типов MIME для конкретных приложений. Например, я заметил, что когда я копирую, восстанавливаю и затем вставляю сообщение Skype в разговор Skype, сообщение больше не «цитируется». Это доказывает, что моя копия имеет недостатки? Есть ли лучший, более точный способ скопировать QMimeData?
После некоторой отладки я обнаружил, что в сообщении Skype есть два формата mimedata.
Text/Plain
тип, содержащий текст самого сообщения и application/x-qt-windows-mime;value="SkypeMessageFragment"
тип, который содержит некоторые xml-подобные данные. Документация Qt по типам MIME указывает на то, что value="..."
описывает, как данные кодируются. Нужно ли мне что-то кодировать или декодировать, чтобы сделать копию моего QMimeData действительной?
Для пользовательских типов MIME, таких как application/x-qt-windows-mime;value="SomeValue"
, реальное имя формата на самом деле SomeValue
(что после value=
между двумя цитатами).
Более точный способ скопировать объект QMimeData будет выглядеть примерно так:
QMimeData * copyMimeData(const QMimeData * mimeReference)
{
QMimeData * mimeCopy = new QMimeData();
foreach(QString format, mimeReference->formats())
{
// Retrieving data
QByteArray data = mimeReference->data(format);
// Checking for custom MIME types
if(format.startsWith("application/x-qt"))
{
// Retrieving true format name
int indexBegin = format.indexOf('"') + 1;
int indexEnd = format.indexOf('"', indexBegin);
format = format.mid(indexBegin, indexEnd - indexBegin);
}
mimeCopy->setData(format, data);
}
return mimeCopy;
}
Других решений пока нет …