forked from qt-creator/qt-creator
Editors: Support drag & drop from bookmarks pane
Change-Id: I9b68d35b04968779f111885ba7a24f18fecfada5 Reviewed-by: Daniel Teske <daniel.teske@digia.com>
This commit is contained in:
@@ -40,7 +40,6 @@
|
||||
#include <QDragEnterEvent>
|
||||
#include <QDropEvent>
|
||||
#include <QMessageBox>
|
||||
#include <QMimeData>
|
||||
#include <QTimer>
|
||||
#include <QUrl>
|
||||
|
||||
@@ -705,8 +704,16 @@ FileName &FileName::appendString(QChar str)
|
||||
return *this;
|
||||
}
|
||||
|
||||
static bool isDesktopFileManagerDrop(const QMimeData *d, QStringList *files = 0)
|
||||
static bool isFileDrop(const QMimeData *d, QList<FileDropSupport::FileSpec> *files = 0)
|
||||
{
|
||||
// internal drop
|
||||
if (const FileDropMimeData *internalData = qobject_cast<const FileDropMimeData *>(d)) {
|
||||
if (files)
|
||||
*files = internalData->files();
|
||||
return true;
|
||||
}
|
||||
|
||||
// external drop
|
||||
if (files)
|
||||
files->clear();
|
||||
// Extract dropped files from Mime data.
|
||||
@@ -723,7 +730,7 @@ static bool isDesktopFileManagerDrop(const QMimeData *d, QStringList *files = 0)
|
||||
if (!fileName.isEmpty()) {
|
||||
hasFiles = true;
|
||||
if (files)
|
||||
files->push_back(fileName);
|
||||
files->append(FileDropSupport::FileSpec(fileName));
|
||||
else
|
||||
break; // No result list, sufficient for checking
|
||||
}
|
||||
@@ -745,27 +752,12 @@ QStringList FileDropSupport::mimeTypesForFilePaths()
|
||||
return QStringList() << QStringLiteral("text/uri-list");
|
||||
}
|
||||
|
||||
QMimeData *FileDropSupport::mimeDataForFilePaths(const QStringList &filePaths)
|
||||
{
|
||||
QList<QUrl> localUrls = Utils::transform(filePaths, [filePaths](const QString &path) {
|
||||
return QUrl::fromLocalFile(path);
|
||||
});
|
||||
auto data = new QMimeData;
|
||||
data->setUrls(localUrls);
|
||||
return data;
|
||||
}
|
||||
|
||||
QMimeData *FileDropSupport::mimeDataForFilePath(const QString &filePath)
|
||||
{
|
||||
return mimeDataForFilePaths(QStringList() << filePath);
|
||||
}
|
||||
|
||||
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())
|
||||
if (isFileDrop(dee->mimeData())
|
||||
&& (!m_filterFunction || m_filterFunction(dee)))
|
||||
event->accept();
|
||||
else
|
||||
@@ -776,8 +768,8 @@ bool FileDropSupport::eventFilter(QObject *obj, QEvent *event)
|
||||
return true;
|
||||
} else if (event->type() == QEvent::Drop) {
|
||||
auto de = static_cast<QDropEvent *>(event);
|
||||
QStringList tempFiles;
|
||||
if (isDesktopFileManagerDrop(de->mimeData(), &tempFiles)
|
||||
QList<FileSpec> tempFiles;
|
||||
if (isFileDrop(de->mimeData(), &tempFiles)
|
||||
&& (!m_filterFunction || m_filterFunction(de))) {
|
||||
event->accept();
|
||||
de->acceptProposedAction();
|
||||
@@ -800,6 +792,21 @@ void FileDropSupport::emitFilesDropped()
|
||||
m_files.clear();
|
||||
}
|
||||
|
||||
void FileDropMimeData::addFile(const QString &filePath, int line, int column)
|
||||
{
|
||||
// standard mime data
|
||||
QList<QUrl> currentUrls = urls();
|
||||
currentUrls.append(QUrl::fromLocalFile(filePath));
|
||||
setUrls(currentUrls);
|
||||
// special mime data
|
||||
m_files.append(FileDropSupport::FileSpec(filePath, line, column));
|
||||
}
|
||||
|
||||
QList<FileDropSupport::FileSpec> FileDropMimeData::files() const
|
||||
{
|
||||
return m_files;
|
||||
}
|
||||
|
||||
} // namespace Utils
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
@@ -35,6 +35,7 @@
|
||||
#include <QCoreApplication>
|
||||
#include <QXmlStreamWriter> // Mac.
|
||||
#include <QMetaType>
|
||||
#include <QMimeData>
|
||||
#include <QStringList>
|
||||
|
||||
#include <functional>
|
||||
@@ -48,7 +49,6 @@ class QDir;
|
||||
class QDropEvent;
|
||||
class QFile;
|
||||
class QFileInfo;
|
||||
class QMimeData;
|
||||
class QTemporaryFile;
|
||||
class QTextStream;
|
||||
class QWidget;
|
||||
@@ -202,18 +202,22 @@ class QTCREATOR_UTILS_EXPORT FileDropSupport : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
// returns true if the event should be accepted
|
||||
struct FileSpec {
|
||||
FileSpec(const QString &path, int r = -1, int c = -1) : filePath(path), line(r), column(c) {}
|
||||
QString filePath;
|
||||
int line;
|
||||
int column;
|
||||
};
|
||||
// returns true if the event should be accepted
|
||||
typedef std::function<bool(QDropEvent*)> DropFilterFunction;
|
||||
|
||||
FileDropSupport(QWidget *parentWidget, const DropFilterFunction &filterFunction
|
||||
= DropFilterFunction());
|
||||
|
||||
static QStringList mimeTypesForFilePaths();
|
||||
static QMimeData *mimeDataForFilePaths(const QStringList &filePaths);
|
||||
static QMimeData *mimeDataForFilePath(const QString &filePath);
|
||||
|
||||
signals:
|
||||
void filesDropped(const QStringList &files);
|
||||
void filesDropped(const QList<Utils::FileDropSupport::FileSpec> &files);
|
||||
|
||||
protected:
|
||||
bool eventFilter(QObject *obj, QEvent *event);
|
||||
@@ -223,10 +227,21 @@ private slots:
|
||||
|
||||
private:
|
||||
DropFilterFunction m_filterFunction;
|
||||
QStringList m_files;
|
||||
QList<FileSpec> m_files;
|
||||
|
||||
};
|
||||
|
||||
class QTCREATOR_UTILS_EXPORT FileDropMimeData : public QMimeData
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
void addFile(const QString &filePath, int line = -1, int column = -1);
|
||||
QList<FileDropSupport::FileSpec> files() const;
|
||||
|
||||
private:
|
||||
QList<FileDropSupport::FileSpec> m_files;
|
||||
};
|
||||
|
||||
} // namespace Utils
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
@@ -229,6 +229,8 @@ BookmarkView::BookmarkView(BookmarkManager *manager) :
|
||||
setSelectionModel(manager->selectionModel());
|
||||
setSelectionMode(QAbstractItemView::SingleSelection);
|
||||
setSelectionBehavior(QAbstractItemView::SelectRows);
|
||||
setDragEnabled(true);
|
||||
setDragDropMode(QAbstractItemView::DragOnly);
|
||||
|
||||
connect(this, SIGNAL(clicked(QModelIndex)),
|
||||
this, SLOT(gotoBookmark(QModelIndex)));
|
||||
@@ -408,6 +410,35 @@ QVariant BookmarkManager::data(const QModelIndex &index, int role) const
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
Qt::ItemFlags BookmarkManager::flags(const QModelIndex &index) const
|
||||
{
|
||||
if (!index.isValid() || index.column() !=0 || index.row() < 0 || index.row() >= m_bookmarksList.count())
|
||||
return Qt::NoItemFlags;
|
||||
return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled;
|
||||
}
|
||||
|
||||
Qt::DropActions BookmarkManager::supportedDragActions() const
|
||||
{
|
||||
return Qt::MoveAction;
|
||||
}
|
||||
|
||||
QStringList BookmarkManager::mimeTypes() const
|
||||
{
|
||||
return FileDropSupport::mimeTypesForFilePaths();
|
||||
}
|
||||
|
||||
QMimeData *BookmarkManager::mimeData(const QModelIndexList &indexes) const
|
||||
{
|
||||
auto data = new Utils::FileDropMimeData;
|
||||
foreach (const QModelIndex &index, indexes) {
|
||||
if (!index.isValid() || index.column() != 0 || index.row() < 0 || index.row() >= m_bookmarksList.count())
|
||||
continue;
|
||||
Bookmark *bookMark = m_bookmarksList.at(index.row());
|
||||
data->addFile(bookMark->fileName(), bookMark->lineNumber());
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
void BookmarkManager::toggleBookmark()
|
||||
{
|
||||
BaseTextEditor *editor = BaseTextEditor::currentTextEditor();
|
||||
|
@@ -74,6 +74,11 @@ public:
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const;
|
||||
int columnCount(const QModelIndex &parent = QModelIndex()) const;
|
||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
|
||||
Qt::ItemFlags flags(const QModelIndex &index) const;
|
||||
|
||||
Qt::DropActions supportedDragActions() const;
|
||||
QStringList mimeTypes() const;
|
||||
QMimeData *mimeData(const QModelIndexList &indexes) const;
|
||||
|
||||
// this QItemSelectionModel is shared by all views
|
||||
QItemSelectionModel *selectionModel() const;
|
||||
|
@@ -426,14 +426,14 @@ Qt::ItemFlags DocumentModelPrivate::flags(const QModelIndex &index) const
|
||||
|
||||
QMimeData *DocumentModelPrivate::mimeData(const QModelIndexList &indexes) const
|
||||
{
|
||||
QStringList filePaths;
|
||||
auto data = new Utils::FileDropMimeData;
|
||||
foreach (const QModelIndex &index, indexes) {
|
||||
const DocumentModel::Entry *e = DocumentModel::entryAtRow(index.row());
|
||||
if (!e || e->fileName().isEmpty())
|
||||
continue;
|
||||
filePaths.append(e->fileName());
|
||||
data->addFile(e->fileName());
|
||||
}
|
||||
return Utils::FileDropSupport::mimeDataForFilePaths(filePaths);
|
||||
return data;
|
||||
}
|
||||
|
||||
int DocumentModel::rowOfDocument(IDocument *document)
|
||||
|
@@ -577,6 +577,19 @@ IEditor *EditorManagerPrivate::openEditor(EditorView *view, const QString &fileN
|
||||
return result;
|
||||
}
|
||||
|
||||
IEditor *EditorManagerPrivate::openEditorAt(EditorView *view, const QString &fileName, int line,
|
||||
int column, Id editorId,
|
||||
EditorManager::OpenEditorFlags flags, bool *newEditor)
|
||||
{
|
||||
EditorManager::cutForwardNavigationHistory();
|
||||
EditorManager::addCurrentPositionToNavigationHistory();
|
||||
EditorManager::OpenEditorFlags tempFlags = flags | EditorManager::IgnoreNavigationHistory;
|
||||
Core::IEditor *editor = openEditor(view, fileName, editorId, tempFlags, newEditor);
|
||||
if (editor && line != -1)
|
||||
editor->gotoLine(line, column);
|
||||
return editor;
|
||||
}
|
||||
|
||||
IEditor *EditorManagerPrivate::activateEditorForDocument(EditorView *view, IDocument *document,
|
||||
EditorManager::OpenEditorFlags flags)
|
||||
{
|
||||
@@ -2222,14 +2235,8 @@ IEditor *EditorManager::openEditor(const QString &fileName, Id editorId,
|
||||
IEditor *EditorManager::openEditorAt(const QString &fileName, int line, int column,
|
||||
Id editorId, OpenEditorFlags flags, bool *newEditor)
|
||||
{
|
||||
m_instance->cutForwardNavigationHistory();
|
||||
m_instance->addCurrentPositionToNavigationHistory();
|
||||
OpenEditorFlags tempFlags = flags | IgnoreNavigationHistory;
|
||||
Core::IEditor *editor = Core::EditorManager::openEditor(fileName, editorId,
|
||||
tempFlags, newEditor);
|
||||
if (editor && line != -1)
|
||||
editor->gotoLine(line, column);
|
||||
return editor;
|
||||
return EditorManagerPrivate::openEditorAt(EditorManagerPrivate::currentEditorView(),
|
||||
fileName, line, column, editorId, flags, newEditor);
|
||||
}
|
||||
|
||||
// Extract line number suffix. Return the suffix (e.g. ":132") and truncates the filename accordingly.
|
||||
|
@@ -75,6 +75,13 @@ public:
|
||||
Id editorId = Id(),
|
||||
EditorManager::OpenEditorFlags flags = EditorManager::NoFlags,
|
||||
bool *newEditor = 0);
|
||||
static IEditor *openEditorAt(EditorView *view,
|
||||
const QString &fileName,
|
||||
int line,
|
||||
int column = 0,
|
||||
Id editorId = Id(),
|
||||
EditorManager::OpenEditorFlags flags = EditorManager::NoFlags,
|
||||
bool *newEditor = 0);
|
||||
static IEditor *duplicateEditor(IEditor *editor);
|
||||
static IEditor *activateEditor(EditorView *view, IEditor *editor,
|
||||
EditorManager::OpenEditorFlags flags = EditorManager::NoFlags);
|
||||
|
@@ -40,7 +40,6 @@
|
||||
#include <coreplugin/minisplitter.h>
|
||||
#include <coreplugin/editormanager/ieditor.h>
|
||||
#include <coreplugin/findplaceholder.h>
|
||||
#include <utils/fileutils.h>
|
||||
#include <utils/qtcassert.h>
|
||||
|
||||
#include <QDebug>
|
||||
@@ -125,8 +124,8 @@ EditorView::EditorView(SplitterOrView *parentSplitterOrView, QWidget *parent) :
|
||||
auto dropSupport = new Utils::FileDropSupport(this, [this](QDropEvent *event) {
|
||||
return event->source() != m_toolBar; // do not accept drops on ourselves
|
||||
});
|
||||
connect(dropSupport, SIGNAL(filesDropped(QStringList)),
|
||||
this, SLOT(openDroppedFiles(QStringList)));
|
||||
connect(dropSupport, &Utils::FileDropSupport::filesDropped,
|
||||
this, &EditorView::openDroppedFiles);
|
||||
|
||||
updateNavigatorActions();
|
||||
}
|
||||
@@ -350,11 +349,12 @@ void EditorView::closeSplit()
|
||||
EditorManagerPrivate::updateActions();
|
||||
}
|
||||
|
||||
void EditorView::openDroppedFiles(const QStringList &files)
|
||||
void EditorView::openDroppedFiles(const QList<Utils::FileDropSupport::FileSpec> &files)
|
||||
{
|
||||
const int count = files.size();
|
||||
for (int i = 0; i < count; ++i) {
|
||||
EditorManagerPrivate::openEditor(this, files.at(i), Id(),
|
||||
const Utils::FileDropSupport::FileSpec spec = files.at(i);
|
||||
EditorManagerPrivate::openEditorAt(this, spec.filePath, spec.line, spec.column, Id(),
|
||||
i < count - 1 ? EditorManager::DoNotChangeCurrentEditor
|
||||
| EditorManager::DoNotMakeVisible
|
||||
: EditorManager::NoFlags);
|
||||
|
@@ -32,6 +32,8 @@
|
||||
|
||||
#include "coreplugin/id.h"
|
||||
|
||||
#include <utils/fileutils.h>
|
||||
|
||||
#include <QMap>
|
||||
#include <QList>
|
||||
#include <QString>
|
||||
@@ -119,7 +121,7 @@ private slots:
|
||||
void splitVertically();
|
||||
void splitNewWindow();
|
||||
void closeSplit();
|
||||
void openDroppedFiles(const QStringList &files);
|
||||
void openDroppedFiles(const QList<Utils::FileDropSupport::FileSpec> &files);
|
||||
|
||||
private:
|
||||
friend class SplitterOrView; // for setParentSplitterOrView
|
||||
|
@@ -453,8 +453,10 @@ bool EditorToolBar::eventFilter(QObject *obj, QEvent *event)
|
||||
d->m_editorList->currentIndex());
|
||||
if (!entry) // no document
|
||||
return Utils::StyledBar::eventFilter(obj, event);
|
||||
auto *drag = new QDrag(this);
|
||||
drag->setMimeData(Utils::FileDropSupport::mimeDataForFilePath(entry->fileName()));
|
||||
auto drag = new QDrag(this);
|
||||
auto data = new Utils::FileDropMimeData;
|
||||
data->addFile(entry->fileName());
|
||||
drag->setMimeData(data);
|
||||
Qt::DropAction action = drag->exec(Qt::MoveAction | Qt::CopyAction, Qt::MoveAction);
|
||||
if (action == Qt::MoveAction)
|
||||
emit currentDocumentMoved();
|
||||
|
@@ -73,7 +73,7 @@
|
||||
#include <coreplugin/progressmanager/progressmanager_p.h>
|
||||
#include <coreplugin/progressmanager/progressview.h>
|
||||
#include <coreplugin/settingsdatabase.h>
|
||||
#include <utils/fileutils.h>
|
||||
#include <utils/algorithm.h>
|
||||
#include <utils/historycompleter.h>
|
||||
#include <utils/hostosinfo.h>
|
||||
#include <utils/qtcassert.h>
|
||||
@@ -212,8 +212,8 @@ MainWindow::MainWindow() :
|
||||
auto dropSupport = new Utils::FileDropSupport(this, [](QDropEvent *event) {
|
||||
return event->source() == 0; // only accept drops from the "outside" (e.g. file manager)
|
||||
});
|
||||
connect(dropSupport, SIGNAL(filesDropped(QStringList)),
|
||||
this, SLOT(openDroppedFiles(QStringList)));
|
||||
connect(dropSupport, &Utils::FileDropSupport::filesDropped,
|
||||
this, &MainWindow::openDroppedFiles);
|
||||
}
|
||||
|
||||
void MainWindow::setSidebarVisible(bool visible)
|
||||
@@ -384,10 +384,14 @@ void MainWindow::closeEvent(QCloseEvent *event)
|
||||
event->accept();
|
||||
}
|
||||
|
||||
void MainWindow::openDroppedFiles(const QStringList &files)
|
||||
void MainWindow::openDroppedFiles(const QList<Utils::FileDropSupport::FileSpec> &files)
|
||||
{
|
||||
raiseWindow();
|
||||
openFiles(files, ICore::SwitchMode);
|
||||
QStringList filePaths = Utils::transform(files,
|
||||
[](const Utils::FileDropSupport::FileSpec &spec) -> QString {
|
||||
return spec.filePath;
|
||||
});
|
||||
openFiles(filePaths, ICore::SwitchMode);
|
||||
}
|
||||
|
||||
IContext *MainWindow::currentContextObject() const
|
||||
|
@@ -35,6 +35,7 @@
|
||||
#include "dialogs/newdialog.h"
|
||||
|
||||
#include <utils/appmainwindow.h>
|
||||
#include <utils/fileutils.h>
|
||||
|
||||
#include <QMap>
|
||||
#include <QColor>
|
||||
@@ -148,7 +149,7 @@ private slots:
|
||||
void updateFocusWidget(QWidget *old, QWidget *now);
|
||||
void setSidebarVisible(bool visible);
|
||||
void destroyVersionDialog();
|
||||
void openDroppedFiles(const QStringList &files);
|
||||
void openDroppedFiles(const QList<Utils::FileDropSupport::FileSpec> &files);
|
||||
void restoreWindowState();
|
||||
void newItemDialogFinished();
|
||||
|
||||
|
@@ -500,13 +500,13 @@ QStringList FlatModel::mimeTypes() const
|
||||
|
||||
QMimeData *FlatModel::mimeData(const QModelIndexList &indexes) const
|
||||
{
|
||||
QStringList filePaths;
|
||||
auto data = new Utils::FileDropMimeData;
|
||||
foreach (const QModelIndex &index, indexes) {
|
||||
Node *node = nodeForIndex(index);
|
||||
if (qobject_cast<FileNode *>(node))
|
||||
filePaths.append(node->path());
|
||||
data->addFile(node->path());
|
||||
}
|
||||
return Utils::FileDropSupport::mimeDataForFilePaths(filePaths);
|
||||
return data;
|
||||
}
|
||||
|
||||
QModelIndex FlatModel::indexForNode(const Node *node_)
|
||||
|
Reference in New Issue
Block a user