Changeset 444
- Timestamp:
- Dec 30, 2009, 2:32:09 AM (15 years ago)
- Location:
- trunk/src/gui/kernel
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
TabularUnified trunk/src/gui/kernel/qdnd_pm.cpp ¶
r442 r444 57 57 #include "qt_os2.h" 58 58 59 #define QDND_DEBUG // in pair with qmime_pm.cpp59 //#define QDND_DEBUG // in pair with qmime_pm.cpp 60 60 61 61 #ifdef QDND_DEBUG … … 89 89 bool hasFormat_sys(const QString &mimeType); 90 90 QStringList formats_sys(); 91 QVariant retrieveData_sys(const QString &mimeType, QVariant::Type type); 91 QVariant retrieveData_sys(const QString &mimeType, 92 QVariant::Type preferredType); 92 93 93 94 private: … … 209 210 210 211 QVariant QPMDragData::retrieveData_sys(const QString &mimeType, 211 QVariant::Type type)212 QVariant::Type preferredType) 212 213 { 213 214 QVariant result; … … 222 223 foreach (QPMMime::DropWorker *w, workers) { 223 224 if (w->hasFormat(mimeType)) { 224 result = w->retrieveData(mimeType, type);225 result = w->retrieveData(mimeType, preferredType); 225 226 break; 226 227 } … … 270 271 MRESULT qt_dispatchDragAndDrop(QWidget *widget, const QMSG &qmsg) 271 272 { 272 // @todo maybe delete last*Op variables 273 274 static HWND lastDragOverHwnd = 0; // last target window 273 static QWidget *lastDragOverWidget = 0; // last target widget 275 274 static USHORT lastDragOverOp = 0; // last DM_DRAGOVER operation 276 275 277 276 static USHORT supportedOps = 0; // operations supported by all items 277 static bool sourceAllowsOp = false; // does source allow requested operation 278 278 279 279 static USHORT lastDropReply = DOR_NEVERDROP; // last reply to DM_DRAGOVER 280 280 static USHORT lastOpRequest = DO_UNKNOWN; // last op requested in DM_DRAGOVER 281 281 282 static Qt::DropAction lastProposedAction = Qt:: IgnoreAction; // last proposed action282 static Qt::DropAction lastProposedAction = Qt::CopyAction; // last proposed action 283 283 static QRect lastAnswerRect; // last accepted rectangle from the target 284 284 // @todo use lastAnswerRect to compress DM_DRAGOVER events … … 289 289 290 290 BOOL ok = FALSE; 291 292 QDragManager *manager = QDragManager::self(); 291 293 292 294 switch (qmsg.msg) { … … 294 296 DEBUG(("DM_DRAGOVER: hwnd %lX di %p x %d y %d", qmsg.hwnd, qmsg.mp1, 295 297 SHORT1FROMMP(qmsg.mp2), SHORT2FROMMP(qmsg.mp2))); 296 297 bool first = lastDragOverHwnd != qmsg.hwnd;298 if (first) {299 // the first DM_DRAGOVER message300 lastDragOverHwnd = qmsg.hwnd;301 lastDropReply = DOR_NEVERDROP;302 lastOpRequest = DO_UNKNOWN;303 lastProposedAction = Qt::IgnoreAction;304 lastAnswerRect = QRect();305 supportedOps = DO_COPYABLE | DO_MOVEABLE | DO_LINKABLE;306 // ensure drag data is reset (just in case of a wrong msg flow...)307 dragData.reset();308 }309 310 Q_ASSERT(first || widget->acceptDrops());311 if (!widget->acceptDrops()) {312 if (!first) {313 // Odin32 apps are dramatically bogus, they continue to send314 // DM_DRAGOVER even if we reply DOR_NEVERDROP. Simulate315 // DM_DRAGLEAVE316 lastDragOverHwnd = 0;317 dragData.reset();318 }319 return MRFROM2SHORT(DOR_NEVERDROP, 0);320 }321 298 322 299 DRAGINFO *info = (DRAGINFO *)qmsg.mp1; … … 325 302 if (!ok || !info) 326 303 return MRFROM2SHORT(DOR_NEVERDROP, 0); 304 305 // flip y coordinate 306 QPoint pnt(info->xDrop, info->yDrop); 307 pnt.setY(QApplication::desktop()->height() - (pnt.y() + 1)); 308 pnt = widget->mapFromGlobal(pnt); 309 310 QWidget *dragOverWidget = widget->childAt(pnt); 311 if (!dragOverWidget) 312 dragOverWidget = widget; 313 314 bool first = lastDragOverWidget != dragOverWidget; 315 if (first) { 316 // the first DM_DRAGOVER message 317 if (lastDragOverWidget != 0) { 318 // send drag leave to the old widget 319 dragData.reset(); 320 QPointer<QWidget> dragOverWidgetGuard(dragOverWidget); 321 QDragLeaveEvent dle; 322 QApplication::sendEvent(lastDragOverWidget, &dle); 323 if (!dragOverWidgetGuard) { 324 dragOverWidget = widget->childAt(pnt); 325 if (!dragOverWidget) 326 dragOverWidget = widget; 327 } 328 } 329 lastDragOverWidget = dragOverWidget; 330 lastDragOverOp = 0; 331 supportedOps = DO_COPYABLE | DO_MOVEABLE | DO_LINKABLE; 332 sourceAllowsOp = false; 333 lastDropReply = DOR_NEVERDROP; 334 lastOpRequest = DO_UNKNOWN; 335 lastProposedAction = manager->defaultAction(toQDragDropActions(supportedOps), 336 Qt::NoModifier); 337 lastAnswerRect = QRect(); 338 // ensure drag data is reset (just in case of a wrong msg flow...) 339 dragData.reset(); 340 } 341 342 if (!dragOverWidget->acceptDrops()) { 343 // We don't reply with DOR_NEVERDROP here because in this 344 // case PM will stop sending DM_DRAGOVER to the given HWND but 345 // we may have another non-native child (that has the same HWND) 346 // at a different position that accepts drops 347 DrgFreeDraginfo(info); 348 return MRFROM2SHORT(DOR_NODROP, 0); 349 } 327 350 328 351 USHORT dropReply = DOR_DROP; … … 352 375 if (dropReply != DOR_NEVERDROP) { 353 376 354 bool sourceAllowsOp = false;355 356 377 if (first || lastDragOverOp != info->usOperation) { 357 378 // the current drop operation was changed by a modifier key … … 373 394 // the drop. Other platforms seem to do the same. 374 395 375 // flip y coordinate376 QPoint pnt(info->xDrop, info->yDrop);377 pnt.setY(QApplication::desktop()->height() - (pnt.y() + 1));378 pnt = widget->mapFromGlobal(pnt);379 380 QDragManager *manager = QDragManager::self();381 396 QMimeData *data = manager->source() ? manager->dragPrivate()->data : manager->dropData; 382 397 … … 388 403 QApplication::mouseButtons(), 389 404 QApplication::keyboardModifiers()); 390 QApplication::sendEvent( widget, &dee);405 QApplication::sendEvent(dragOverWidget, &dee); 391 406 // if not allowed or not accepted, always reply DOR_NODROP 392 // to have DM_DRAGOVER delivered to us again in any case407 // to have DM_DRAGOVER delivered to us again for a new test 393 408 if (sourceAllowsOp && dee.isAccepted()) { 394 409 dropReply = DOR_DROP; 395 410 action = dee.dropAction(); 411 lastProposedAction = dee.proposedAction(); 396 412 lastAnswerRect = dee.answerRect(); 397 413 } else { … … 410 426 dme.setDropAction(action); 411 427 dme.accept(); 412 QApplication::sendEvent( widget, &dme);428 QApplication::sendEvent(dragOverWidget, &dme); 413 429 if (sourceAllowsOp && dme.isAccepted()) { 414 430 dropReply = DOR_DROP; 415 431 action = dme.dropAction(); 432 lastProposedAction = dme.proposedAction(); 433 lastAnswerRect = dme.answerRect(); 416 434 } else { 417 435 dropReply = DOR_NODROP; … … 431 449 432 450 // Odin32 apps produce incorrect message flow, ignore 433 Q_ASSERT(lastDragOver Hwnd!= 0);434 if (lastDragOver Hwnd== 0)451 Q_ASSERT(lastDragOverWidget != 0); 452 if (lastDragOverWidget == 0) 435 453 return 0; 436 454 437 lastDragOverHwnd = 0; 455 QDragLeaveEvent de; 456 QApplication::sendEvent(lastDragOverWidget, &de); 457 458 lastDragOverWidget = 0; 438 459 dragData.reset(); 439 460 440 if (!widget->acceptDrops())441 return 0;442 443 QDragLeaveEvent de;444 QApplication::sendEvent(widget, &de);445 461 return 0; 446 462 } … … 449 465 450 466 // Odin32 apps produce incorrect message flow, ignore 451 Q_ASSERT(lastDragOver Hwnd!= 0);452 if (lastDragOver Hwnd== 0)467 Q_ASSERT(lastDragOverWidget != 0); 468 if (lastDragOverWidget == 0) 453 469 return 0; 454 470 455 471 // Odin32 apps send DM_DROP even if we replied DOR_NEVERDROP or 456 472 // DOR_NODROP, simulate DM_DRAGLEAVE 457 Q_ASSERT(lastDropReply == DM_DROP); 458 if (lastDropReply != DM_DROP) { 459 WinSendMsg(qmsg.hwnd, DM_DRAGLEAVE, 0, 0); 473 Q_ASSERT(lastDropReply == DOR_DROP); 474 if (lastDropReply != DOR_DROP) { 475 QMSG qmsg2 = qmsg; 476 qmsg2.msg = DM_DRAGLEAVE; 477 qt_dispatchDragAndDrop(widget, qmsg2); 460 478 return 0; 461 479 } 462 463 lastDragOverHwnd = 0;464 465 Q_ASSERT(widget->acceptDrops());466 if (!widget->acceptDrops())467 return 0;468 480 469 481 DRAGINFO *info = (DRAGINFO *)qmsg.mp1; … … 471 483 Q_ASSERT(ok && info); 472 484 if (!ok || !info) 473 return MRFROM2SHORT(DOR_NEVERDROP, 0); 474 475 Q_ASSERT(lastOpRequest == info->usOperation); 485 return 0; 476 486 477 487 // flip y coordinate … … 480 490 pnt = widget->mapFromGlobal(pnt); 481 491 492 Q_ASSERT(lastOpRequest == info->usOperation); 493 494 Q_ASSERT(lastDragOverWidget->acceptDrops()); 495 if (!lastDragOverWidget->acceptDrops()) { 496 DrgDeleteDraginfoStrHandles(info); 497 DrgFreeDraginfo(info); 498 return 0; 499 } 500 482 501 QDragManager *manager = QDragManager::self(); 483 502 QMimeData *data = manager->source() ? manager->dragPrivate()->data : manager->dropData; … … 492 511 de.setDropAction(action); 493 512 494 QApplication::sendEvent( widget, &de);513 QApplication::sendEvent(lastDragOverWidget, &de); 495 514 496 515 if (lastDropReply == DOR_DROP) 497 516 de.accept(); 498 517 518 lastDragOverWidget = 0; 499 519 dragData.reset(de.isAccepted()); 500 520 -
TabularUnified trunk/src/gui/kernel/qmime.h ¶
r443 r444 148 148 virtual HWND hwnd() const = 0; 149 149 // methods implemented if isExclusive() == TRUE and itemCount() == 0 150 virtual DRAGINFO *createDragInfo(const char *name, USHORT supportedOps)151 { return NULL; }150 virtual DRAGINFO *createDragInfo(const QString &targetName, USHORT supportedOps) 151 { return 0; } 152 152 // methods implemented if itemCount() >= 0 153 153 virtual QByteArray composeFormatString() { return QByteArray(); } 154 154 virtual bool prepare(const char *drm, const char *drf, DRAGITEM *item, 155 ULONG itemIndex) { return FALSE; }155 ULONG itemIndex) { return false; } 156 156 virtual void defaultFileType(const char *&type, const char *&ext) {}; 157 157 … … 185 185 { 186 186 public: 187 virtual const QString &format(const char *drf) const = 0;187 virtual QString format(const char *drf) const = 0; 188 188 virtual bool provide(const char *drf, const QByteArray &allData, 189 189 ULONG itemIndex, QByteArray &itemData) = 0; … … 217 217 virtual bool hasFormat(const QString &mimeType) const = 0; 218 218 virtual QStringList formats() const = 0; 219 virtual QVariant retrieveData(const QString &mimeType, QVariant::Type type) const = 0; 219 virtual QVariant retrieveData(const QString &mimeType, 220 QVariant::Type preferredType) const = 0; 220 221 221 222 private: … … 236 237 bool hasFormat(const QString &mimeType) const; 237 238 QStringList formats() const; 238 QVariant retrieveData(const QString &mimeType, QVariant::Type type) const; 239 QVariant retrieveData(const QString &mimeType, 240 QVariant::Type preferredType) const; 239 241 240 242 // QPMObjectWindow interface -
TabularUnified trunk/src/gui/kernel/qmime_pm.cpp ¶
r442 r444 60 60 #include "qdir.h" 61 61 62 #define QDND_DEBUG // in pair with qdnd_pm.cpp62 //#define QDND_DEBUG // in pair with qdnd_pm.cpp 63 63 64 64 #ifdef QDND_DEBUG … … 769 769 } 770 770 771 // @todo 771 // @todo remove 772 772 //int QPMMime::DefaultDropWorker::formatCount() const 773 773 //{ … … 814 814 815 815 QVariant QPMMime::DefaultDropWorker::retrieveData(const QString &mimeType, 816 QVariant::Type type) const817 { 818 Q_UNUSED( type);819 820 DEBUG(() << "DefaultDropWorker::retrieveData (" << mimeType << ")");816 QVariant::Type preferredType) const 817 { 818 Q_UNUSED(preferredType); 819 820 DEBUG(() << "DefaultDropWorker::retrieveData: mimeType" << mimeType); 821 821 822 822 QVariant ret; … … 1000 1000 bool ok = file.remove(); 1001 1001 Q_ASSERT((ok = ok)); 1002 Q_UNUSED(ok); 1002 1003 } else { 1003 1004 Q_ASSERT(xfer->hstrRenderToName); … … 1088 1089 if (d->sending_DM_RENDER) 1089 1090 { 1091 #ifndef QT_NO_DEBUG 1090 1092 DRAGTRANSFER *xfer = (DRAGTRANSFER *) mp1; 1091 #ifndef QT_NO_DEBUG1092 1093 qWarning("Drag item 0x%08lX sent DM_RENDERCOMPLETE w/o first " 1093 1094 "replying to DM_RENDER!\n" … … 1420 1421 All subclasses must reimplement this pure virtual function. 1421 1422 */ 1423 1424 // @todo add DnD interfaces docs 1422 1425 1423 1426 // static … … 1788 1791 QPMMime::DefaultDragWorker *QPMMime::defaultExclDragWorker() 1789 1792 { 1790 static DefaultDragWorker defExclDragWorker( false /* exclusive */);1793 static DefaultDragWorker defExclDragWorker(true /* exclusive */); 1791 1794 return &defExclDragWorker; 1792 1795 } … … 1821 1824 QVariant::Type preferredType) const; 1822 1825 1826 #if !defined(QT_NO_DRAGANDDROP) 1827 1828 // Direct Manipulation (DND) converter interface 1829 DragWorker *dragWorkerFor(const QString &mimeType, QMimeData *mimeData); 1830 DropWorker *dropWorkerFor(DRAGINFO *info); 1831 1832 class NativeFileDrag : public DragWorker, public QPMObjectWindow 1833 { 1834 public: 1835 // DragWorker interface 1836 bool cleanup(bool isCancelled) { return true; } // always disallow Move 1837 bool isExclusive() const { return true; } 1838 ULONG itemCount() const { return 0; } // super exclusive 1839 HWND hwnd() const { return QPMObjectWindow::hwnd(); } 1840 DRAGINFO *createDragInfo(const QString &targetName, USHORT supportedOps); 1841 // QPMObjectWindow interface (dummy implementation, we don't need to interact) 1842 MRESULT message(ULONG msg, MPARAM mp1, MPARAM mp2) { return 0; } 1843 }; 1844 1845 class NativeFileDrop : public DropWorker 1846 { 1847 public: 1848 // DropWorker interface 1849 bool isExclusive() const { return true; } 1850 bool hasFormat(const QString &mimeType) const; 1851 QStringList formats() const; 1852 QVariant retrieveData(const QString &mimeType, 1853 QVariant::Type preferredType) const; 1854 }; 1855 1856 class TextDragProvider : public DefaultDragWorker::Provider 1857 { 1858 public: 1859 TextDragProvider() : exclusive(false) {} 1860 bool exclusive; 1861 // Provider interface 1862 QString format(const char *drf) const; 1863 bool provide(const char *drf, const QByteArray &allData, 1864 ULONG itemIndex, QByteArray &itemData); 1865 void fileType(const char *drf, const char *&type, const char *&ext); 1866 }; 1867 1868 class TextDropProvider : public DefaultDropWorker::Provider 1869 { 1870 public: 1871 // Provider interface 1872 const char *drf(const QString &mimeType) const; 1873 bool provide(const QString &format, ULONG itemIndex, 1874 const QByteArray &itemData, QByteArray &allData); 1875 }; 1876 1877 #endif // !QT_NO_DRAGANDDROP 1878 1823 1879 const ULONG CF_TextUnicode; 1824 1880 const ULONG CF_TextHtml; 1881 1882 #if !defined(QT_NO_DRAGANDDROP) 1883 NativeFileDrag nativeFileDrag; 1884 NativeFileDrop nativeFileDrop; 1885 TextDragProvider textDragProvider; 1886 TextDropProvider textDropProvider; 1887 #endif // !QT_NO_DRAGANDDROP 1825 1888 }; 1826 1889 … … 1999 2062 } 2000 2063 2064 #if !defined(QT_NO_DRAGANDDROP) 2065 2066 DRAGINFO *QPMMimeText::NativeFileDrag::createDragInfo(const QString &targetName, 2067 USHORT supportedOps) 2068 { 2069 Q_ASSERT(source()); 2070 if (!source()) 2071 return 0; 2072 2073 // obtain the list of files 2074 QList<QUrl> list; 2075 if (source()->hasUrls()) 2076 list = source()->urls(); 2077 ULONG itemCnt = list.count(); 2078 Q_ASSERT(itemCnt); 2079 if (!itemCnt) 2080 return 0; 2081 2082 DEBUG(() << "QPMMimeText::NativeFileDrag: itemCnt" << itemCnt); 2083 2084 DRAGINFO *info = DrgAllocDraginfo(itemCnt); 2085 Q_ASSERT(info); 2086 if (!info) 2087 return 0; 2088 2089 bool ok = true; 2090 QList<QUrl>::iterator it = list.begin(); 2091 for (ULONG i = 0; i < itemCnt; ++i, ++it) { 2092 DRAGITEM *item = DrgQueryDragitemPtr(info, i); 2093 Q_ASSERT(item); 2094 if (!item) { 2095 ok = false; 2096 break; 2097 } 2098 2099 QByteArray fileName = QFile::encodeName(QDir::convertSeparators(it->toLocalFile())); 2100 2101 int sep = fileName.lastIndexOf('\\'); 2102 Q_ASSERT(sep > 0 && sep < fileName.length() - 1); 2103 if (sep <= 0 || sep >= fileName.length() - 1) { 2104 ok = false; 2105 break; 2106 } 2107 2108 item->hstrSourceName = DrgAddStrHandle(fileName.data() + sep + 1); 2109 fileName.truncate(sep + 1); 2110 item->hstrContainerName = DrgAddStrHandle(fileName); 2111 2112 DEBUG(() << "QPMMimeText::NativeFileDrag: item" << i 2113 << "dir" << queryHSTR(item->hstrContainerName) 2114 << "name" << queryHSTR(item->hstrSourceName)); 2115 2116 item->hwndItem = hwnd(); 2117 item->ulItemID = 0; 2118 item->hstrType = DrgAddStrHandle(DRT_UNKNOWN); 2119 item->hstrRMF = DrgAddStrHandle("<DRM_OS2FILE,DRF_UNKNOWN>"); 2120 item->hstrTargetName = 0; 2121 item->cxOffset = 0; 2122 item->cyOffset = 0; 2123 item->fsControl = 0; 2124 item->fsSupportedOps = supportedOps; 2125 } 2126 2127 if (!ok) { 2128 DrgFreeDraginfo(info); 2129 info = 0; 2130 } 2131 2132 return info; 2133 } 2134 2135 bool QPMMimeText::NativeFileDrop::hasFormat(const QString &mimeType) const 2136 { 2137 return mimeType == QLatin1String("text/uri-list"); 2138 } 2139 2140 QStringList QPMMimeText::NativeFileDrop::formats() const 2141 { 2142 QStringList mimes; 2143 mimes << QLatin1String("text/uri-list"); 2144 return mimes; 2145 } 2146 2147 QVariant QPMMimeText::NativeFileDrop::retrieveData(const QString &mimeType, 2148 QVariant::Type preferredType) const 2149 { 2150 QVariant result; 2151 2152 Q_ASSERT(info()); 2153 if (!info()) 2154 return result; 2155 2156 ULONG itemCount = DrgQueryDragitemCount(info()); 2157 Q_ASSERT(itemCount); 2158 if (!itemCount) 2159 return result; 2160 2161 // sanity check 2162 if (mimeType != QLatin1String("text/uri-list")) 2163 return result; 2164 2165 QList<QVariant> urls; 2166 2167 for (ULONG i = 0; i < itemCount; ++i) { 2168 DRAGITEM *item = DrgQueryDragitemPtr(info(), i); 2169 Q_ASSERT(item); 2170 QByteArray fullName; 2171 if (!item || !canTargetRenderAsOS2File(item, &fullName)) 2172 return result; 2173 QString fn = QFile::decodeName(fullName); 2174 urls += QUrl::fromLocalFile(fn).toString(); 2175 } 2176 2177 if (preferredType == QVariant::Url && urls.size() == 1) 2178 result = urls.at(0); 2179 else if (!urls.isEmpty()) 2180 result = urls; 2181 2182 return result; 2183 } 2184 2185 QString QPMMimeText::TextDragProvider::format(const char *drf) const 2186 { 2187 QString result; 2188 2189 if (qstrcmp(drf, "DRF_TEXT") == 0) { 2190 if (exclusive) 2191 result = QLatin1String("text/uri-list"); 2192 else 2193 result = QLatin1String("text/plain"); 2194 } 2195 return result; 2196 } 2197 2198 bool QPMMimeText::TextDragProvider::provide(const char *drf, 2199 const QByteArray &allData, 2200 ULONG itemIndex, 2201 QByteArray &itemData) 2202 { 2203 if (qstrcmp(drf, "DRF_TEXT") == 0) { 2204 if (exclusive) { 2205 // locate the required item 2206 int dataSize = allData.size(); 2207 if (!dataSize) 2208 return false; 2209 int begin = 0, end = 0, next = 0; 2210 do { 2211 begin = next; 2212 end = allData.indexOf('\r', begin); 2213 if (end >= 0) { 2214 next = end + 1; 2215 if (next < dataSize && allData[next] == '\n') 2216 ++next; 2217 } else { 2218 end = allData.indexOf('\n', begin); 2219 if (end >= 0) 2220 next = end + 1; 2221 } 2222 } while (itemIndex-- && end >= 0 && next < dataSize); 2223 int urlLen = end - begin; 2224 if (urlLen <= 0) 2225 return false; 2226 QUrl url = QUrl(QString::fromUtf8(allData.data() + begin, urlLen)); 2227 if (!url.isValid()) 2228 return false; 2229 itemData = url.toEncoded(); 2230 } else { 2231 itemData = allData; 2232 } 2233 return true; 2234 } 2235 return false; 2236 } 2237 2238 void QPMMimeText::TextDragProvider::fileType(const char *drf, const char *&type, 2239 const char *&ext) 2240 { 2241 if (qstrcmp(drf, "DRF_TEXT") == 0) { 2242 if (exclusive) { 2243 type = "UniformResourceLocator"; 2244 // no extension for URLs 2245 } else { 2246 type = DRT_TEXT; 2247 ext = "txt"; 2248 } 2249 } 2250 }; 2251 2252 const char *QPMMimeText::TextDropProvider::drf(const QString &mimeType) const 2253 { 2254 // sanity check 2255 if (mimeType == QLatin1String("text/plain") || 2256 mimeType == QLatin1String("text/uri-list")) 2257 return "DRF_TEXT"; 2258 return 0; 2259 } 2260 2261 bool QPMMimeText::TextDropProvider::provide(const QString &mimeType, 2262 ULONG itemIndex, 2263 const QByteArray &itemData, 2264 QByteArray &allData) 2265 { 2266 if (mimeType == QLatin1String("text/plain")) { 2267 allData = itemData; 2268 return true; 2269 } 2270 2271 if (mimeType == QLatin1String("text/uri-list")) { 2272 QUrl url = QUrl::fromEncoded(itemData); 2273 if (!url.isValid()) 2274 return false; 2275 // append the URL to the list 2276 allData += url.toString().toUtf8(); 2277 allData += "\r\n"; 2278 return true; 2279 } 2280 2281 return false; 2282 } 2283 2284 QPMMime::DragWorker *QPMMimeText::dragWorkerFor(const QString &mimeType, 2285 QMimeData *mimeData) 2286 { 2287 if (mimeType == QLatin1String("text/plain")) { 2288 // add a cooperative provider 2289 textDragProvider.exclusive = false; 2290 DefaultDragWorker *defWorker = defaultCoopDragWorker(); 2291 defWorker->addProvider("DRF_TEXT", &textDragProvider); 2292 return defWorker; 2293 } 2294 2295 if (mimeType == QLatin1String("text/uri-list")) { 2296 // see what kind of items text/uri-list represents 2297 QList<QUrl> urls = mimeData->urls(); 2298 int fileCnt = 0; 2299 foreach (const QUrl &url, urls) { 2300 if (url.scheme() == QLatin1String("file")) 2301 ++fileCnt; 2302 } 2303 if (fileCnt && fileCnt == urls.count()) { 2304 // all items are local files, return an exclusive file drag worker 2305 return &nativeFileDrag; 2306 } 2307 if (urls.count() && !fileCnt) { 2308 // all items are non-files, add an exclusive provider for the 2309 // specified item count 2310 textDragProvider.exclusive = true; 2311 DefaultDragWorker *defWorker = defaultExclDragWorker(); 2312 bool ok = defWorker->addProvider("DRF_TEXT", &textDragProvider, 2313 urls.count()); 2314 return ok ? defWorker : 0; 2315 } 2316 // if items are mixed, we return NULL to fallback to QPMMimeAnyMime 2317 } 2318 2319 return 0; 2320 } 2321 2322 QPMMime::DropWorker *QPMMimeText::dropWorkerFor(DRAGINFO *info) 2323 { 2324 ULONG itemCount = DrgQueryDragitemCount(info); 2325 Q_ASSERT(itemCount); 2326 if (!itemCount) 2327 return 0; 2328 2329 if (itemCount == 1) { 2330 DRAGITEM *item = DrgQueryDragitemPtr(info, 0); 2331 Q_ASSERT(item); 2332 if (!item) 2333 return 0; 2334 // proceed only if the target cannot render DRM_OS2FILE on its own 2335 // and if the item type is not "UniformResourceLocator" (which will be 2336 // processed below) 2337 if (!canTargetRenderAsOS2File(item) && 2338 !DrgVerifyType(item, "UniformResourceLocator")) { 2339 DefaultDropWorker *defWorker = defaultDropWorker(); 2340 // check that we support one of DRMs and the format is DRF_TEXT 2341 if (defWorker->canRender(item, "DRF_TEXT")) { 2342 // add a cooperative provider (can coexist with others) 2343 defWorker->addProvider(QLatin1String("text/plain"), 2344 &textDropProvider); 2345 return defWorker; 2346 } 2347 return 0; 2348 } 2349 } 2350 2351 // Either the target can render DRM_OS2FILE on its own (so it's a valid 2352 // file/directory name), or it's an "UniformResourceLocator", or there is 2353 // more than one drag item. Check that all items are of either one type 2354 // or another. If so, we can represent them as 'text/uri-list'. 2355 bool allAreFiles = true; 2356 bool allAreURLs = true; 2357 DefaultDropWorker *defWorker = defaultDropWorker(); 2358 for (ULONG i = 0; i < itemCount; ++i) { 2359 DRAGITEM *item = DrgQueryDragitemPtr(info, i); 2360 Q_ASSERT(item); 2361 if (!item) 2362 return 0; 2363 if (allAreFiles) 2364 allAreFiles &= canTargetRenderAsOS2File(item); 2365 if (allAreURLs) 2366 allAreURLs &= DrgVerifyType(item, "UniformResourceLocator") && 2367 defWorker->canRender(item, "DRF_TEXT"); 2368 if (!allAreFiles && !allAreURLs) 2369 return 0; 2370 } 2371 2372 if (allAreFiles) { 2373 // return an exclusive drop worker 2374 return &nativeFileDrop; 2375 } 2376 2377 // add an exclusive provider (can neither coexist with other workers 2378 // or providers) 2379 bool ok = defWorker->addExclusiveProvider(QLatin1String("text/uri-list"), 2380 &textDropProvider); 2381 return ok ? defWorker : 0; 2382 } 2383 2384 #endif // !QT_NO_DRAGANDDROP 2385 2001 2386 //////////////////////////////////////////////////////////////////////////////// 2002 2387
Note:
See TracChangeset
for help on using the changeset viewer.