PDA

View Full Version : Drop item from view outside the window



folibis
15th June 2012, 02:47
I have application with QTreeView which contents an image of remote file system (webdav) and QTreeView contents local file system.
I want to implement drag'n'drop actions for my app.
It works perfectly when i move items between my app's widgets or from outside my app. in QAbstractItemModel::dropMimeData i can control all activity. It looks like that:


bool MyModel::dropMimeData (const QMimeData * data, Qt::DropAction action, int row, int column, const QModelIndex & parent)
{
QList<QUrl> urls = data->urls();
foreach(const QUrl url,urls)
{
LocalFileItem * item = static_cast<RemoteFileItem *>(parent.internalPointer());
if(url.scheme() == "file")
copeLocalFile(item,url);
// url looks like dav:///public/test.txt
else if(url.scheme() == "dav")
{
QString remoteFile = url.path();
copyRemoteFile(remoteFile,item);
}
}
return false;
}

It also works good when I copy file from local tree to the desktop, or even to another place outside my app. I just set correct url like that:


QMimeData * MyModel::mimeData (const QModelIndexList & indexes) const
{
QMimeData * mimeData = new QMimeData();
QList<QUrl> urls;
foreach (const QModelIndex index, indexes)
{
if (index.isValid())
{
FileItem * item = static_cast<FileItem*>(index.internalPointer());
urls.append(item.url()); // url looks like file://c://test.txt
}
}
mimeData->setUrls(urls);
return mimeData;
}
QStringList MyModel::mimeTypes() const
{
QStringList types;
types << "text/uri-list";
return types;
}

But the problem is to copy from remote tree to desktop. All drop actions are controlled by OS. So I cannot handle the moment when my item actually was dropped.
It should be noted that coppied file not exists in local file system while dropping.

I have an idea how to solve this problem:

reimplement QMimeData and method retrieveData() like that:

QVariant MimeData::retrieveData (const QString & mimeType, QVariant::Type type) const
{
//Qt::MouseButtons buttons = QApplication::mouseButtons ();
// here i need check if mouse buttom was release(item was dropped), create temporary file, copy content of remote file into temp file and return path to this file;
return QMimeData::retrieveData(mimeType,type);
}
but I cannot find the way to get state of mouse button, QApplication::mouseButtons does not returns actual state.

Any other ideas?

amleto
15th June 2012, 08:26
QApplication::mouseButtons does not returns actual state.

please explain.

wysota
15th June 2012, 08:33
I don't see how doing anything with QMimeData is going to help you handle drops on areas not belonging to you. Your MIME object will simply be ignored if you drop the drag on a foreign area and that area doesn't want to handle your drop.

folibis
15th June 2012, 11:07
QApplication::mouseButtons does not returns actual state.

please explain.
At the beginning of the drag operation QApplication::mouseButtons return Qt::LeftButton and it is OK. when you release the button (item dropped) it still returns
Qt::LeftButton. Even if you press right button while moving dragged item it still returns Qt::LeftButton.

Added after 20 minutes:


I don't see how doing anything with QMimeData is going to help you handle drops on areas not belonging to you.

I used my own class inherited from QMimeData. So I found that retrieveData was called every time when dragged object was moved over desktop or folder and files at the desktop. Even when this object was dropped on the desktop this function was called. That exactly wat I need. In order to mark out the drop action I check state of left button.
But it is not works as was described above.


Your MIME object will simply be ignored if you drop the drag on a foreign area and that area doesn't want to handle your drop.
I provide correct MIME type (text/uri-list) and correct MIME data(for example file://c:/test.txt) so my obect will be accepted for drop