Index: /trunk/src/gui/kernel/qdnd_pm.cpp
===================================================================
--- /trunk/src/gui/kernel/qdnd_pm.cpp	(revision 464)
+++ /trunk/src/gui/kernel/qdnd_pm.cpp	(revision 465)
@@ -1024,6 +1024,6 @@
     static ULONG itemID = 0;
 
-    const char *type = 0;
-    const char *ext = 0;
+    QString type;
+    QString ext;
     firstWorker->defaultFileType(type, ext);
 
@@ -1043,8 +1043,6 @@
             name = QString(QLatin1String("%1 %2")).arg(targetName).arg(i + 1);
 
-        if (ext) {
-            name += QLatin1Char('.');
-            name += QFile::decodeName(QByteArray(ext));
-        }
+        if (!ext.isEmpty())
+            name += QString(QLatin1String(".%1")).arg(ext);
 
         DEBUG(() << "QPMCoopDragWorker: item" << i << ": type" << type
@@ -1062,5 +1060,6 @@
         item->hwndItem = hwnd();
         item->ulItemID = itemID ++;
-        item->hstrType = DrgAddStrHandle(type ? type : DRT_UNKNOWN);
+        item->hstrType = DrgAddStrHandle(!type.isEmpty() ?
+                                         QFile::encodeName(type) : DRT_UNKNOWN);
         item->hstrRMF = DrgAddStrHandle(allFormats);
         item->hstrContainerName = 0;
Index: /trunk/src/gui/kernel/qmime.h
===================================================================
--- /trunk/src/gui/kernel/qmime.h	(revision 464)
+++ /trunk/src/gui/kernel/qmime.h	(revision 465)
@@ -154,5 +154,5 @@
         virtual bool prepare(const char *drm, const char *drf, DRAGITEM *item,
                              ULONG itemIndex) { return false; }
-        virtual void defaultFileType(const char *&type, const char *&ext) {};
+        virtual void defaultFileType(QString &type, QString &ext) {};
 
     private:
@@ -169,5 +169,5 @@
         virtual ~DefaultDragWorker();
 
-        // DragpWorker interface
+        // DragWorker interface
         bool cleanup(bool isCancelled);
         bool isExclusive() const;
@@ -177,5 +177,5 @@
         bool prepare(const char *drm, const char *drf, DRAGITEM *item,
                      ULONG itemIndex);
-        void defaultFileType(const char *&type, const char *&ext);
+        void defaultFileType(QString &type, QString &ext);
 
         // QPMObjectWindow interface
@@ -188,9 +188,8 @@
             virtual bool provide(const char *drf, const QByteArray &allData,
                                  ULONG itemIndex, QByteArray &itemData) = 0;
-            virtual void fileType(const char *drf, const char *&type,
-                                  const char *&ext) {};
+            virtual void fileType(const char *drf, QString &type, QString &ext) {};
         };
 
-        bool addProvider(const char *drf, Provider *provider,
+        bool addProvider(const QByteArray &drf, Provider *provider,
                          ULONG itemCount = 1);
 
@@ -246,5 +245,5 @@
         {
         public:
-            virtual const char *drf(const QString &mimeType) const = 0;
+            virtual QByteArray drf(const QString &mimeType) const = 0;
             virtual bool provide(const QString &mimeType, ULONG itemIndex,
                                  const QByteArray &itemData,
@@ -255,5 +254,5 @@
         bool addExclusiveProvider(const QString &mimeType, Provider *provider);
 
-        static bool canRender(DRAGITEM *item, const char *drf );
+        static bool canRender(DRAGITEM *item, const char *drf);
         static bool getSupportedRMFs(DRAGITEM *item, QList<QByteArrayList> &list);
 
Index: /trunk/src/gui/kernel/qmime_pm.cpp
===================================================================
--- /trunk/src/gui/kernel/qmime_pm.cpp	(revision 464)
+++ /trunk/src/gui/kernel/qmime_pm.cpp	(revision 465)
@@ -213,5 +213,5 @@
 }
 
-// -----------------------------------------------------------------------------
+//------------------------------------------------------------------------------
 
 struct QPMMime::DefaultDragWorker::Data
@@ -248,5 +248,5 @@
     {
         DrfProvider() : prov(0) {}
-        DrfProvider(const char *d, Provider *p) : drf(d), prov(p) {}
+        DrfProvider(const QByteArray &d, Provider *p) : drf(d), prov(p) {}
         QByteArray drf;
         Provider *prov;
@@ -421,6 +421,6 @@
 }
 
-void QPMMime::DefaultDragWorker::defaultFileType(const char *&type,
-                                                 const char *&ext)
+void QPMMime::DefaultDragWorker::defaultFileType(QString &type,
+                                                 QString &ext)
 {
     Q_ASSERT(d->providers.count());
@@ -580,5 +580,5 @@
                         req->sharedMem = ptr;
                         DEBUG(() << "DefaultDragWorker: Created shared memory "
-                                    "object" << ptr);
+                                    "object" << (void *)ptr);
 #ifndef QT_NO_DEBUG
                     } else {
@@ -665,5 +665,5 @@
 }
 
-bool QPMMime::DefaultDragWorker::addProvider(const char *drf, Provider *provider,
+bool QPMMime::DefaultDragWorker::addProvider(const QByteArray &drf, Provider *provider,
                                              ULONG itemCnt /* = 1 */)
 {
@@ -671,6 +671,6 @@
     d->cleanupRequests();
 
-    Q_ASSERT(drf && provider && itemCnt >= 1);
-    if (drf && provider && itemCnt >= 1) {
+    Q_ASSERT(!drf.isEmpty() && provider && itemCnt >= 1);
+    if (!drf.isEmpty() && provider && itemCnt >= 1) {
         if (d->providers.count() == 0) {
             // first provider
@@ -828,7 +828,7 @@
         return ret;
 
-    const char *drf = provider->drf(mimeType);
-    Q_ASSERT(drf);
-    if (!drf)
+    QByteArray drf = provider->drf(mimeType);
+    Q_ASSERT(!drf.isEmpty());
+    if (drf.isEmpty())
         return ret;
 
@@ -849,7 +849,9 @@
 
     HSTR rmfOS2File =
-        DrgAddStrHandle(QString().sprintf("<DRM_OS2FILE,%s>", drf).toLocal8Bit());
+        DrgAddStrHandle(QString().sprintf("<DRM_OS2FILE,%s>",
+                                          drf.data()).toLocal8Bit());
     HSTR rmfSharedMem =
-        DrgAddStrHandle(QString().sprintf("<DRM_SHAREDMEM,%s>", drf).toLocal8Bit());
+        DrgAddStrHandle(QString().sprintf("<DRM_SHAREDMEM,%s>",
+                                          drf.data()).toLocal8Bit());
 
     MRESULT mrc;
@@ -1815,5 +1817,5 @@
 #endif // !QT_NO_DRAGANDDROP
 
-////////////////////////////////////////////////////////////////////////////////
+//------------------------------------------------------------------------------
 
 class QPMMimeText : public QPMMime
@@ -1873,5 +1875,5 @@
         bool provide(const char *drf, const QByteArray &allData,
                      ULONG itemIndex, QByteArray &itemData);
-        void fileType(const char *drf, const char *&type, const char *&ext);
+        void fileType(const char *drf, QString &type, QString &ext);
     };
 
@@ -1880,6 +1882,6 @@
     public:
         // Provider interface
-        const char *drf(const QString &mimeType) const;
-        bool provide(const QString &format, ULONG itemIndex,
+        QByteArray drf(const QString &mimeType) const;
+        bool provide(const QString &mimeType, ULONG itemIndex,
                      const QByteArray &itemData, QByteArray &allData);
     };
@@ -2246,24 +2248,25 @@
 }
 
-void QPMMimeText::TextDragProvider::fileType(const char *drf, const char *&type,
-                                             const char *&ext)
+void QPMMimeText::TextDragProvider::fileType(const char *drf,
+                                             QString &type, QString &ext)
 {
     if (qstrcmp(drf, "DRF_TEXT") == 0) {
         if (exclusive) {
-            type = "UniformResourceLocator";
+            type = QLatin1String("UniformResourceLocator");
             // no extension for URLs
+            ext = QString::null;
         } else {
-            type = DRT_TEXT;
-            ext = "txt";
+            type = QLatin1String(DRT_TEXT);
+            ext = QLatin1String("txt");
         }
     }
 };
 
-const char *QPMMimeText::TextDropProvider::drf(const QString &mimeType) const
+QByteArray QPMMimeText::TextDropProvider::drf(const QString &mimeType) const
 {
     // sanity check
     if (mimeType == QLatin1String("text/plain") ||
         mimeType == QLatin1String("text/uri-list"))
-        return "DRF_TEXT";
+        return QByteArray("DRF_TEXT");
     return 0;
 }
@@ -2400,5 +2403,5 @@
 #endif // !QT_NO_DRAGANDDROP
 
-////////////////////////////////////////////////////////////////////////////////
+//------------------------------------------------------------------------------
 
 class QPMMimeImage : public QPMMime
@@ -2489,5 +2492,5 @@
 }
 
-////////////////////////////////////////////////////////////////////////////////
+//------------------------------------------------------------------------------
 
 class QPMMimeAnyMime : public QPMMime
@@ -2507,4 +2510,37 @@
                                QVariant::Type preferredType) const;
 
+#if !defined(QT_NO_DRAGANDDROP)
+
+    // Direct Manipulation (DND) converter interface
+    DragWorker *dragWorkerFor(const QString &mimeType, QMimeData *mimeData);
+    DropWorker *dropWorkerFor(DRAGINFO *info);
+
+    class AnyDragProvider : public DefaultDragWorker::Provider
+    {
+    public:
+        AnyDragProvider(QPMMimeAnyMime *am) : anyMime(am) {}
+        // Provider interface
+        QString format(const char *drf) const;
+        bool provide(const char *drf, const QByteArray &allData,
+                     ULONG itemIndex, QByteArray &itemData);
+        void fileType(const char *drf, QString &type, QString &ext);
+    private:
+        QPMMimeAnyMime *anyMime;
+    };
+
+    class AnyDropProvider : public DefaultDropWorker::Provider
+    {
+    public:
+        AnyDropProvider(QPMMimeAnyMime *am) : anyMime(am) {}
+        // Provider interface
+        QByteArray drf(const QString &mimeType) const;
+        bool provide(const QString &mimeType, ULONG itemIndex,
+                     const QByteArray &itemData, QByteArray &allData);
+    private:
+        QPMMimeAnyMime *anyMime;
+    };
+
+#endif // !QT_NO_DRAGANDDROP
+
 private:
     ULONG registerMimeType(const QString &mime) const;
@@ -2517,4 +2553,17 @@
     static QString mimePrefix;
     static QString customPrefix;
+
+#if !defined(QT_NO_DRAGANDDROP)
+
+    static ULONG drfToCf(const char *drf);
+    static QByteArray cfToDrf(ULONG cf);
+
+    AnyDragProvider anyDragProvider;
+    AnyDropProvider anyDropProvider;
+
+//    friend class AnyDragProvider;
+//    friend class AnyDropProvider;
+
+#endif // !QT_NO_DRAGANDDROP
 };
 
@@ -2525,4 +2574,8 @@
 
 QPMMimeAnyMime::QPMMimeAnyMime()
+#if !defined(QT_NO_DRAGANDDROP)
+    : anyDragProvider(AnyDragProvider(this))
+    , anyDropProvider(AnyDropProvider(this))
+#endif // !QT_NO_DRAGANDDROP
 {
     //MIME Media-Types
@@ -2637,4 +2690,139 @@
 }
 
+#if !defined(QT_NO_DRAGANDDROP)
+
+QString QPMMimeAnyMime::AnyDragProvider::format(const char *drf) const
+{
+    ULONG cf = drfToCf(drf);
+    if (cf) {
+        QString mime = anyMime->mimeMap.value(cf);
+        if (!mime.isEmpty())
+            return mime;
+    }
+
+    // There must always be a match since the given drf is associated with this
+    // provider by dragWorkerFor() and all necessary mappings are there.
+    Q_ASSERT(false);
+    return QString::null;
+}
+
+bool QPMMimeAnyMime::AnyDragProvider::provide(const char *drf,
+                                              const QByteArray &allData,
+                                              ULONG itemIndex,
+                                              QByteArray &itemData)
+{
+    Q_UNUSED(drf);
+    Q_UNUSED(itemIndex);
+
+    // always straight through coversion
+    itemData = allData;
+    return true;
+}
+
+void QPMMimeAnyMime::AnyDragProvider::fileType(const char *drf,
+                                               QString &type, QString &ext)
+{
+    // file type = mime
+    type = format(drf);
+    Q_ASSERT(!type.isEmpty());
+
+    // no way to determine the extension
+    ext = QString::null;
+};
+
+QByteArray QPMMimeAnyMime::AnyDropProvider::drf(const QString &mimeType) const
+{
+    ULONG cf = anyMime->cfMap.value(mimeType);
+    if (cf)
+        return cfToDrf(cf);
+
+    // There must always be a match since the given drf is associated with this
+    // provider by dragWorkerFor() and all necessary mappings are there.
+    Q_ASSERT(false);
+    return QByteArray();
+}
+
+bool QPMMimeAnyMime::AnyDropProvider::provide(const QString &mimeType,
+                                              ULONG itemIndex,
+                                              const QByteArray &itemData,
+                                              QByteArray &allData)
+{
+    Q_UNUSED(mimeType);
+    Q_UNUSED(itemIndex);
+
+    // always straight through coversion
+    allData = itemData;
+    return true;
+}
+
+QPMMime::DragWorker *QPMMimeAnyMime::dragWorkerFor(const QString &mimeType,
+                                                   QMimeData *mimeData)
+{
+    ULONG cf = cfMap.value(mimeType);
+    if (!cf)
+        cf = registerMimeType(mimeType);
+    if (cf) {
+        DefaultDragWorker *defWorker = defaultCoopDragWorker();
+        // add a cooperative provider
+        defWorker->addProvider(cfToDrf(cf), &anyDragProvider);
+        return defWorker;
+    }
+
+    Q_ASSERT(false);
+    return 0;
+}
+
+QPMMime::DropWorker *QPMMimeAnyMime::dropWorkerFor(DRAGINFO *info)
+{
+    ULONG itemCount = DrgQueryDragitemCount(info);
+    Q_ASSERT(itemCount);
+    if (!itemCount)
+        return 0;
+
+    if (itemCount == 1) {
+        DRAGITEM *item = DrgQueryDragitemPtr(info, 0);
+        Q_ASSERT(item);
+        if (!item)
+            return 0;
+
+        DefaultDropWorker *defWorker = defaultDropWorker();
+        bool atLeastOneSupported = false;
+
+        // check that we support one of DRMs and the format is CF_hhhhhhh
+        QList<QByteArrayList> list;
+        defWorker->getSupportedRMFs(item, list);
+        foreach(const QByteArrayList &mech, list) {
+            QByteArrayList::const_iterator it = mech.begin();
+            Q_ASSERT(it != mech.end());
+            DEBUG(() << "QPMMimeAnyMime: Supported drm:" << *it);
+            for (++it; it != mech.end(); ++it) {
+                const QByteArray &drf = *it;
+                ULONG cf = drfToCf(drf);
+                if (cf) {
+                    DEBUG(() << "QPMMimeAnyMime: Supported drf:" << drf);
+                    QString mime = mimeMap.value(cf);
+                    if (mime.isEmpty())
+                        mime = registerFormat(cf);
+                    Q_ASSERT(!mime.isEmpty());
+                    if (!mime.isEmpty()) {
+                        DEBUG(() << "QPMMimeAnyMime: Will provide [" << mime
+                                 << "] for drf" << drf);
+                        // add a cooperative provider (can coexist with others)
+                        defWorker->addProvider(mime, &anyDropProvider);
+                        atLeastOneSupported = true;
+                    }
+                }
+            }
+        }
+
+        if (atLeastOneSupported)
+            return defWorker;
+    }
+
+    return 0;
+}
+
+#endif // !QT_NO_DRAGANDDROP
+
 ULONG QPMMimeAnyMime::registerMimeType(const QString &mime) const
 {
@@ -2689,5 +2877,23 @@
 }
 
-////////////////////////////////////////////////////////////////////////////////
+#if !defined(QT_NO_DRAGANDDROP)
+
+// static
+ULONG QPMMimeAnyMime::drfToCf(const char *drf)
+{
+    if (qstrncmp(drf, "CF_", 3) == 0)
+        return QString(QLatin1String(drf + 3)).toULong(0, 16);
+    return 0;
+}
+
+// static
+QByteArray QPMMimeAnyMime::cfToDrf(ULONG cf)
+{
+    return QString().sprintf("CF_%08lX", cf).toLatin1();
+}
+
+#endif // !QT_NO_DRAGANDDROP
+
+//------------------------------------------------------------------------------
 
 QPMMimeList::QPMMimeList()
