Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Proper way to copy a QMimeData object

Tags:

c++

clipboard

qt

I am developing a Qt application to store whatever goes through the clipboard so I can restore it later. My approach was to retrieve the QMimeData from the QApplication::clipboard() and store it in a QList<QMimeData *>. As the data in the clipboard is volatile, I have to copy the QMimeData returned by QClipboard::mimeData(). There is no copy constructor for QMimeData so I figured that I would copy it like this :

const QMimeData * clipboardData = _clipboard->mimeData();
QMimeData * mimeCopy = new QMimeData();

foreach(const QString & format, clipboardData->formats())
    mimeCopy->setData(format, clipboardData->data(format))

where _clipboard is the QApplication::clipboard().

This works relatively fine except for some application-specific MIME types. For example, I noticed that when I copy, restore and then paste a Skype message in a Skype conversation, the message is not "quoted" anymore. Does This proves that my copy is flawed ? Is there a better, more accurate way to copy QMimeData ?

After some debugging, I found out that there are two formats in a Skype message mimedata. A Text/Plain type containing the text of the message itself and a application/x-qt-windows-mime;value="SkypeMessageFragment" type which contains some xml-like data. Qt's documentation on MIME types indicates that the value="..." describes how the data is encoded. Do I have to encode or decode something at some point to make my QMimeData's copy valid ?

like image 658
Guillaume Depardon Avatar asked Dec 07 '12 11:12

Guillaume Depardon


1 Answers

For custom MIME types like application/x-qt-windows-mime;value="SomeValue", the real format name is in fact SomeValue (what is after value=, between the two quotes).

A more accurate way to copy a QMimeData object would then be something like this :

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;
}
like image 107
Guillaume Depardon Avatar answered Sep 24 '22 00:09

Guillaume Depardon