forked from qt-creator/qt-creator
Core: Refactor file dropping into reusable component
Change-Id: I42d291d8f8c0e76e289e56055044c369e8be8a89 Reviewed-by: David Schulz <david.schulz@digia.com>
This commit is contained in:
@@ -36,7 +36,11 @@
|
|||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QDateTime>
|
#include <QDateTime>
|
||||||
|
#include <QDragEnterEvent>
|
||||||
|
#include <QDropEvent>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
|
#include <QMimeData>
|
||||||
|
#include <QTimer>
|
||||||
|
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
#include <qt_windows.h>
|
#include <qt_windows.h>
|
||||||
@@ -679,6 +683,72 @@ FileName &FileName::appendString(QChar str)
|
|||||||
return *this;
|
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
|
} // namespace Utils
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|||||||
@@ -35,6 +35,7 @@
|
|||||||
#include <QCoreApplication>
|
#include <QCoreApplication>
|
||||||
#include <QXmlStreamWriter> // Mac.
|
#include <QXmlStreamWriter> // Mac.
|
||||||
#include <QMetaType>
|
#include <QMetaType>
|
||||||
|
#include <QStringList>
|
||||||
|
|
||||||
namespace Utils {class FileName; }
|
namespace Utils {class FileName; }
|
||||||
|
|
||||||
@@ -192,6 +193,26 @@ private:
|
|||||||
bool m_autoRemove;
|
bool m_autoRemove;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class QTCREATOR_UTILS_EXPORT FileDropSupport : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
FileDropSupport(QWidget *parentWidget);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void filesDropped(const QStringList &files);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool eventFilter(QObject *obj, QEvent *event);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void emitFilesDropped();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QStringList m_files;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace Utils
|
} // namespace Utils
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|||||||
@@ -74,6 +74,7 @@
|
|||||||
#include <coreplugin/progressmanager/progressmanager_p.h>
|
#include <coreplugin/progressmanager/progressmanager_p.h>
|
||||||
#include <coreplugin/progressmanager/progressview.h>
|
#include <coreplugin/progressmanager/progressview.h>
|
||||||
#include <coreplugin/settingsdatabase.h>
|
#include <coreplugin/settingsdatabase.h>
|
||||||
|
#include <utils/fileutils.h>
|
||||||
#include <utils/historycompleter.h>
|
#include <utils/historycompleter.h>
|
||||||
#include <utils/hostosinfo.h>
|
#include <utils/hostosinfo.h>
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
@@ -87,7 +88,6 @@
|
|||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
#include <QUrl>
|
#include <QUrl>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QMimeData>
|
|
||||||
|
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QCloseEvent>
|
#include <QCloseEvent>
|
||||||
@@ -211,7 +211,10 @@ MainWindow::MainWindow() :
|
|||||||
//signal(SIGINT, handleSigInt);
|
//signal(SIGINT, handleSigInt);
|
||||||
|
|
||||||
statusBar()->setProperty("p_styled", true);
|
statusBar()->setProperty("p_styled", true);
|
||||||
setAcceptDrops(true);
|
|
||||||
|
auto dropSupport = new Utils::FileDropSupport(this);
|
||||||
|
connect(dropSupport, SIGNAL(filesDropped(QStringList)),
|
||||||
|
this, SLOT(openDroppedFiles(QStringList)));
|
||||||
|
|
||||||
#if defined(Q_OS_MAC)
|
#if defined(Q_OS_MAC)
|
||||||
MacFullScreen::addFullScreen(this);
|
MacFullScreen::addFullScreen(this);
|
||||||
@@ -386,61 +389,10 @@ void MainWindow::closeEvent(QCloseEvent *event)
|
|||||||
event->accept();
|
event->accept();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for desktop file manager file drop events
|
void MainWindow::openDroppedFiles(const QStringList &files)
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::dragEnterEvent(QDragEnterEvent *event)
|
|
||||||
{
|
|
||||||
if (isDesktopFileManagerDrop(event->mimeData()) && m_filesToOpenDelayed.isEmpty())
|
|
||||||
event->accept();
|
|
||||||
else
|
|
||||||
event->ignore();
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::dropEvent(QDropEvent *event)
|
|
||||||
{
|
|
||||||
QStringList files;
|
|
||||||
if (isDesktopFileManagerDrop(event->mimeData(), &files)) {
|
|
||||||
event->accept();
|
|
||||||
m_filesToOpenDelayed.append(files);
|
|
||||||
QTimer::singleShot(50, this, SLOT(openDelayedFiles()));
|
|
||||||
} else {
|
|
||||||
event->ignore();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::openDelayedFiles()
|
|
||||||
{
|
|
||||||
if (m_filesToOpenDelayed.isEmpty())
|
|
||||||
return;
|
|
||||||
raiseWindow();
|
raiseWindow();
|
||||||
openFiles(m_filesToOpenDelayed, ICore::SwitchMode);
|
openFiles(files, ICore::SwitchMode);
|
||||||
m_filesToOpenDelayed.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
IContext *MainWindow::currentContextObject() const
|
IContext *MainWindow::currentContextObject() const
|
||||||
|
|||||||
@@ -137,8 +137,6 @@ public slots:
|
|||||||
protected:
|
protected:
|
||||||
virtual void changeEvent(QEvent *e);
|
virtual void changeEvent(QEvent *e);
|
||||||
virtual void closeEvent(QCloseEvent *event);
|
virtual void closeEvent(QCloseEvent *event);
|
||||||
virtual void dragEnterEvent(QDragEnterEvent *event);
|
|
||||||
virtual void dropEvent(QDropEvent *event);
|
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void openFile();
|
void openFile();
|
||||||
@@ -151,7 +149,7 @@ private slots:
|
|||||||
void updateFocusWidget(QWidget *old, QWidget *now);
|
void updateFocusWidget(QWidget *old, QWidget *now);
|
||||||
void setSidebarVisible(bool visible);
|
void setSidebarVisible(bool visible);
|
||||||
void destroyVersionDialog();
|
void destroyVersionDialog();
|
||||||
void openDelayedFiles();
|
void openDroppedFiles(const QStringList &files);
|
||||||
void restoreWindowState();
|
void restoreWindowState();
|
||||||
void newItemDialogFinished();
|
void newItemDialogFinished();
|
||||||
|
|
||||||
@@ -213,8 +211,6 @@ private:
|
|||||||
|
|
||||||
QToolButton *m_toggleSideBarButton;
|
QToolButton *m_toggleSideBarButton;
|
||||||
QColor m_overrideColor;
|
QColor m_overrideColor;
|
||||||
|
|
||||||
QStringList m_filesToOpenDelayed;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
|||||||
Reference in New Issue
Block a user