views:

265

answers:

1

I am trying to trap drag and drop events from the standard Apple address book app to my Qt app. This code works fine with Qt 4.4. on Mac OS X 10.4:

void 
MyView::contentsDropEvent( QDropEvent* e )
{
    QList<QUrl> urls = e->mimeData()->urls();
    ...

I can then use the URL to get the vCard. Marvellous.

But from Mac OS X 10.5 the apple address book no longer seems to support text/uri-list. So e->mimeData()->urls() returns an empty list. Worse still, e->mimeData()->formats() returns an empty list. How do I find out which vCards they dragged?

Here is a comment from a Nokia Qt engineer on this problem:

"Adressbook stopped providing drop data as text/uri-list compatible flavor data in OS 10.5. Not much we can do about that. The flavor they provide instead is 'public.vcard'. We could put up support for this as an implementation request, but my gut feeling is that this is too application specific, and can just as well be implemented by the app developer by subclassing QMacMimeData"

But there is no QMacMimeData in the Qt 4.4 or 4.5 documentation. Any ideas at how I can find out what they dragged?

A: 

richardmg of Qt/Nokia kindly supplied me with some example code. I have filled in some of the gaps. This now works fine on Mac OS X 10.5.

#include <QtGui>

class VCardMime : public QMacPasteboardMime
{
    public:
    VCardMime() : QMacPasteboardMime(MIME_ALL)
    { }

    QString convertorName()
    {
        return QString("VCardMime");
    }

    bool canConvert(const QString &mime, QString flav)
    {
        return mimeFor(flav) == mime;
    }

    QString mimeFor(QString flav)
    {
        if (flav == QString("public.vcard"))
            return QString("application/x-mycompany-VCard");
        return QString();
    }

    QString flavorFor(const QString &mime)
    {
        if (mime == QString("application/x-mycompany-VCard"))
            return QString("public.vcard");
        return QString();
    }

    QVariant convertToMime(const QString &mime, QList<QByteArray> data, QString flav)
    {
        QByteArray all;
        foreach ( QByteArray i, data )
        {
            all += i;
        }
        return QVariant( all );
    }

    QList<QByteArray> convertFromMime(const QString &mime, QVariant data, QString flav)
    {
        // Todo: implement!
        return QList<QByteArray>();
    }

};

class TestWidget : public QWidget
{

public:
    TestWidget() : QWidget(0)
    {
        new VCardMime();
        setAcceptDrops(true);
    }

    void contentsDropEvent(QDropEvent* e)
    {
        if ( e->mimeData()->hasFormat( "application/x-mycompany-VCard" ) )
        {                
            QString s = QString( e->mimeData()->data( "application/x-mycompany-VCard" ) );

            // s now contains text of vcard

            e->acceptProposedAction();
        }
    }
};

int main(int argc, char **argv)
{
    QApplication app(argc, argv);
    TestWidget wid1;
    wid1.show();
    return app.exec();
}
Andy Brice