Qt 5.4 QDrop event handling
-
Hello,
My customers give me a tricky request which after couple of hours started to look-a-like impossible one. I need to drop files from total commander archive or a file from .zip file in windows explorer. I reimplemented drag and drop events to handle casual files but it seems I can't get anything from those files I need. Only thing that mime data can provide me is some structure from FileGroupDescriptor which is (looking in Qt debugger applied to QByteArray) containing at least file name.
My question is, if I properly decode data from FileGroupDescriptor will I receive a path to zip file or something that I could use to find this archive file if it can how can I decode it? And if not what I can do else ?
-
Hi and welcome to devnet,
AFAIK, that structure contains a list of FileDescriptor the cFileName looks like what you want to get the file your customer dragged over
Hope it helps
-
Hello,
Thanks for reply link you provided gave me at least something to look after, now I realize that from total commander it just can't be done(but I would be glad to see me proven wrong) and from explorer zip archive I need to extract data from Shell IDList Array to get path to zip archive, I've done some research about that array but still clueless...
-
What do you get from total commander ?
-
Hello, sorry I was overwhelmed with work,
well TC gives me File Group Descriptor something, empty File content mime data, and File Group DescriptorW which looks alike the first one, I don't know what to do with those data structures
-
Isn't the file group descriptor a bunch of Filedescriptor that you can parse ?
-
The file descriptor only contains the name of the file, not a full path. There's no way to get the original path but the "FileGroupDescriptorW" type comes in pair with "FileContents" type. You can inspect the size of the file by reading nFileSizeHigh and nFileSizeLow data members of the FILEDESCRIPTOR structure. The data returned for that type is the corresponding "FileContents", so you can for example parse it directly or store it to a file (you get the name for it from the file desctiptor).
Unfortunately there are two problems here that I see:
First is with multiple files. There is a QTBUG-17373 with a fix scheduled for Qt 5.5. Basically right now you can read contents of the first file only. In Qt 5.5 you'll be able to access all of them adding an ";index=XXX" to the "FileContents" type.
The second problem is something you mentioned and I can reproduce it too - the byte array returned for the "FileContents" type is empty. If someone else could confirm this I would consider reporting this as a bug so maybe it could be fixed for 5.5.
-
This is how you can parse the "FileGroupDescriptorW" type data:
QByteArray fgd = evt->mimeData()->data("FileGroupDescriptorW"); LPFILEGROUPDESCRIPTORW fgddata = (LPFILEGROUPDESCRIPTORW)fgd.constData(); unsigned numItems = fgddata->cItems; for(unsigned i = 0; i < numItems; ++i) { FILEDESCRIPTORW& desc = fgddata->fgd[i]; if(desc.dwFlags & FD_FILESIZE) { QString fileName = QString::fromUtf16((const ushort*)desc.cFileName); int fileSize = desc.nFileSizeLow - desc.nFileSizeHigh; QByteArray fileData = evt->mimeData()->data("application/x-qt-windows-mime;value=\"FileContents\""); //only the first file in Qt 5.4 so break; //in Qt 5.5 you could do //QByteArray fileData = evt->mimeData()->data("application/x-qt-windows-mime;value=\"FileContents\";index=" + QString::number(i)); } }