I've written a little file-transfer application written in C++ using Qt 4.x ... it logs into a server, shows the user a list of files available on the server, and lets the user upload or download files.
This all works fine; you can even drag a file in from the desktop (or from an open folder), and when you drop the file icon into the server-files-list-view, the dropped file gets uploaded to the server.
Now I have a request for the opposite action as well... my users would like to be able to drag a file out of the server-files-list-view and onto the desktop, or into an open folder window, and have that file get downloaded into that location.
That seems like a reasonable request, but I don't know how to implement it. Is there a way for a Qt application to find out the directory corresponding to where "drop event" occurred, when the icon was dropped onto the desktop or into an open folder window? Ideally this would be a Qt-based platform-neutral mechanism, but if that doesn't exist, then platform-specific mechanisms for MacOS/X and Windows (XP or higher) would suffice.
Any ideas?
To start a drag, create a QDrag object, and call its exec() function. In most applications, it is a good idea to begin a drag and drop operation only after a mouse button has been pressed and the cursor has been moved a certain distance.
Look at QMimeData
and its documentation, it has a virtual function
virtual QVariant retrieveData ( const QString & mimetype, QVariant::Type type ) const
this means to do you drag to the outside you implement this functions accordingly
class DeferredMimeData : public QMimeData
{
DeferredMimeData(QString downloadFilename) : m_filename(downloadFilename)
virtual QVariant retrieveData (const QString & mimetype, QVariant::Type type) const
{
if (mimetype matches expected && type matches expected)
{
perform download with m_filename
}
}
}
The delayed encoding examples shows this principle.
You will probably also have to override hasFormat
and formats
to provide the appropriate types, application/octet-stream
probably being the one that might get you the most play, you will probably have to read up on how windows specifically handles drag and drop using mime types.
I don't know how you will supply the file name under which the file is saved, but you will probably have to get into the windows side of things. Looking at the source of QWindowsMime
might also help. There might me a multiple step process where you will get requests for text/uri-list
data for the filenames and then application/octet-stream
for the data.
Hope this helps
I think you are going about that in the wrong way.
You don't care where the drop goes to, you just know it was dropped. In the DropEvent, download the file to a temporary location and then set the mime data to be what was downloaded. Granted this may end up with a second copy to the hard drive, it will be cross platform from the start. You may be able to optimize it afterward with platform specific calls.
Take a look at Dropsite example to see how the mime data works from other sources...
Edit:
It looks like the double copy method is the standard if you don't write a shell extension (for windows at least). Filezilla and 7zip both do that, they return a "text/uri-list" mime type with a temp location. This way explorer copies the data from the temp location to the real one. Your application can do the same, create a temp file (or just the name) with no data. Using the delayed encoding example, create the data on the drop. This whole operation is very platform specific it appears. On Linux (running KDE) I can drag and drop just based on mime type. It appears that windows is not as flexible.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With