Changeset 444 for trunk/src/gui/kernel/qmime_pm.cpp
- Timestamp:
- Dec 30, 2009, 2:32:09 AM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
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.