Core: Refactor file dropping into reusable component

Change-Id: I42d291d8f8c0e76e289e56055044c369e8be8a89
Reviewed-by: David Schulz <david.schulz@digia.com>
This commit is contained in:
Eike Ziller
2014-07-07 16:16:49 +02:00
parent 13346936c6
commit 8273b899e9
4 changed files with 99 additions and 60 deletions

View File

@@ -36,7 +36,11 @@
#include <QDir>
#include <QDebug>
#include <QDateTime>
#include <QDragEnterEvent>
#include <QDropEvent>
#include <QMessageBox>
#include <QMimeData>
#include <QTimer>
#ifdef Q_OS_WIN
#include <qt_windows.h>
@@ -679,6 +683,72 @@ FileName &FileName::appendString(QChar str)
return *this;
}
static bool isDesktopFileManagerDrop(const QMimeData *d, QStringList *files = 0)
{
if (files)
files->clear();
// Extract dropped files from Mime data.
if (!d->hasUrls())
return false;
const QList<QUrl> urls = d->urls();
if (urls.empty())
return false;
// Try to find local files
bool hasFiles = false;
const QList<QUrl>::const_iterator cend = urls.constEnd();
for (QList<QUrl>::const_iterator it = urls.constBegin(); it != cend; ++it) {
const QString fileName = it->toLocalFile();
if (!fileName.isEmpty()) {
hasFiles = true;
if (files)
files->push_back(fileName);
else
break; // No result list, sufficient for checking
}
}
return hasFiles;
}
FileDropSupport::FileDropSupport(QWidget *parentWidget)
: QObject(parentWidget)
{
QTC_ASSERT(parentWidget, return);
parentWidget->setAcceptDrops(true);
parentWidget->installEventFilter(this);
}
bool FileDropSupport::eventFilter(QObject *obj, QEvent *event)
{
Q_UNUSED(obj)
if (event->type() == QEvent::DragEnter) {
auto dee = static_cast<QDragEnterEvent *>(event);
if (isDesktopFileManagerDrop(dee->mimeData()))
event->accept();
else
event->ignore();
} else if (event->type() == QEvent::Drop) {
auto de = static_cast<QDropEvent *>(event);
QStringList tempFiles;
if (isDesktopFileManagerDrop(de->mimeData(), &tempFiles)) {
event->accept();
bool needToScheduleEmit = m_files.isEmpty();
m_files.append(tempFiles);
if (needToScheduleEmit) // otherwise we already have a timer pending
QTimer::singleShot(0, this, SLOT(emitFilesDropped()));
} else {
event->ignore();
}
}
return false;
}
void FileDropSupport::emitFilesDropped()
{
QTC_ASSERT(!m_files.isEmpty(), return);
emit filesDropped(m_files);
m_files.clear();
}
} // namespace Utils
QT_BEGIN_NAMESPACE