Commit 4bcf60dc authored by Eike Ziller's avatar Eike Ziller

Type hierarchy: Add drag & drop into editor splits

Change-Id: I8fec78779d4241988bd4987a5d86020cea83d077
Reviewed-by: default avatarDaniel Teske <daniel.teske@digia.com>
parent 4f6ab1a7
......@@ -37,14 +37,14 @@
#include <coreplugin/find/itemviewfind.h>
#include <utils/algorithm.h>
#include <utils/navigationtreeview.h>
#include <utils/annotateditemdelegate.h>
#include <utils/navigationtreeview.h>
#include <QApplication>
#include <QLabel>
#include <QLatin1String>
#include <QModelIndex>
#include <QStackedLayout>
#include <QStandardItemModel>
#include <QVBoxLayout>
using namespace CppEditor;
......@@ -61,6 +61,7 @@ enum ItemRole {
QStandardItem *itemForClass(const CppClass &cppClass)
{
QStandardItem *item = new QStandardItem;
item->setFlags(item->flags() | Qt::ItemIsDragEnabled);
item->setData(cppClass.name, Qt::DisplayRole);
if (cppClass.name != cppClass.qualifiedName)
item->setData(cppClass.qualifiedName, AnnotationRole);
......@@ -87,40 +88,6 @@ QList<CppClass> sortClasses(const QList<CppClass> &cppClasses)
namespace CppEditor {
namespace Internal {
class CppClassLabel : public QLabel
{
public:
CppClassLabel(QWidget *parent)
: QLabel(parent)
{}
void setup(CppClass *cppClass)
{
setText(cppClass->name);
m_link = cppClass->link;
}
void clear()
{
QLabel::clear();
m_link = CppEditorWidget::Link();
}
private:
void mousePressEvent(QMouseEvent *)
{
if (!m_link.hasValidTarget())
return;
Core::EditorManager::openEditorAt(m_link.targetFileName,
m_link.targetLine,
m_link.targetColumn,
Constants::CPPEDITOR_ID);
}
CppEditorWidget::Link m_link;
};
// CppTypeHierarchyWidget
CppTypeHierarchyWidget::CppTypeHierarchyWidget() :
QWidget(0),
......@@ -129,9 +96,9 @@ CppTypeHierarchyWidget::CppTypeHierarchyWidget() :
m_delegate(0),
m_noTypeHierarchyAvailableLabel(0)
{
m_inspectedClass = new CppClassLabel(this);
m_inspectedClass = new TextEditor::TextEditorLinkLabel(this);
m_inspectedClass->setMargin(5);
m_model = new QStandardItemModel(this);
m_model = new CppTypeHierarchyModel(this);
m_treeView = new NavigationTreeView(this);
m_treeView->setActivationMode(Utils::SingleClickActivation);
m_delegate = new AnnotatedItemDelegate(this);
......@@ -141,6 +108,8 @@ CppTypeHierarchyWidget::CppTypeHierarchyWidget() :
m_treeView->setEditTriggers(QAbstractItemView::NoEditTriggers);
m_treeView->setItemDelegate(m_delegate);
m_treeView->setRootIsDecorated(false);
m_treeView->setDragEnabled(true);
m_treeView->setDragDropMode(QAbstractItemView::DragOnly);
connect(m_treeView, &QTreeView::activated, this, &CppTypeHierarchyWidget::onItemActivated);
m_noTypeHierarchyAvailableLabel = new QLabel(tr("No type hierarchy available"), this);
......@@ -190,7 +159,8 @@ void CppTypeHierarchyWidget::perform()
const QSharedPointer<CppElement> &cppElement = evaluator.cppElement();
CppElement *element = cppElement.data();
if (CppClass *cppClass = dynamic_cast<CppClass *>(element)) {
m_inspectedClass->setup(cppClass);
m_inspectedClass->setText(cppClass->name);
m_inspectedClass->setLink(cppClass->link);
QStandardItem *bases = new QStandardItem(tr("Bases"));
m_model->invisibleRootItem()->appendRow(bases);
buildHierarchy(*cppClass, bases, true, &CppClass::bases);
......@@ -257,6 +227,37 @@ Core::NavigationView CppTypeHierarchyFactory::createWidget()
return Core::NavigationView(w);
}
CppTypeHierarchyModel::CppTypeHierarchyModel(QObject *parent)
: QStandardItemModel(parent)
{
}
Qt::DropActions CppTypeHierarchyModel::supportedDragActions() const
{
// copy & move actions to avoid idiotic behavior of drag and drop:
// standard item model removes nodes automatically that are
// dropped anywhere with move action, but we do not want the '+' sign in the
// drag handle that would appear when only allowing copy action
return Qt::CopyAction | Qt::MoveAction;
}
QStringList CppTypeHierarchyModel::mimeTypes() const
{
return FileDropSupport::mimeTypesForFilePaths();
}
QMimeData *CppTypeHierarchyModel::mimeData(const QModelIndexList &indexes) const
{
auto data = new FileDropMimeData;
data->setOverrideFileDropAction(Qt::CopyAction); // do not remove the item from the model
foreach (const QModelIndex &index, indexes) {
auto link = index.data(LinkRole).value<TextEditor::TextEditorWidget::Link>();
if (link.hasValidTarget())
data->addFile(link.targetFileName, link.targetLine, link.targetColumn);
}
return data;
}
} // namespace Internal
} // namespace CppEditor
......@@ -36,19 +36,21 @@
#include <QString>
#include <QWidget>
#include <QStackedWidget>
#include <QStandardItemModel>
QT_BEGIN_NAMESPACE
class QLabel;
class QModelIndex;
class QStackedLayout;
class QStandardItem;
class QStandardItemModel;
template <class> class QVector;
template <class> class QList;
QT_END_NAMESPACE
namespace Core { class IEditor; }
namespace TextEditor { class TextEditorLinkLabel; }
namespace Utils {
class NavigationTreeView;
class AnnotatedItemDelegate;
......@@ -61,6 +63,18 @@ class CppEditorWidget;
class CppClass;
class CppClassLabel;
class CppTypeHierarchyModel : public QStandardItemModel
{
Q_OBJECT
public:
CppTypeHierarchyModel(QObject *parent);
Qt::DropActions supportedDragActions() const;
QStringList mimeTypes() const;
QMimeData *mimeData(const QModelIndexList &indexes) const;
};
class CppTypeHierarchyWidget : public QWidget
{
Q_OBJECT
......@@ -86,7 +100,7 @@ private:
QStackedLayout *m_stackLayout;
QStandardItemModel *m_model;
Utils::AnnotatedItemDelegate *m_delegate;
CppClassLabel *m_inspectedClass;
TextEditor::TextEditorLinkLabel *m_inspectedClass;
QLabel *m_noTypeHierarchyAvailableLabel;
};
......
......@@ -70,6 +70,7 @@
#include <coreplugin/manhattanstyle.h>
#include <coreplugin/find/basetextfind.h>
#include <utils/linecolumnlabel.h>
#include <utils/fileutils.h>
#include <utils/hostosinfo.h>
#include <utils/qtcassert.h>
#include <utils/stylehelper.h>
......@@ -89,6 +90,7 @@
#include <QPainter>
#include <QPrintDialog>
#include <QPrinter>
#include <QDrag>
#include <QScrollBar>
#include <QShortcut>
#include <QStyle>
......@@ -7205,6 +7207,55 @@ void TextEditorWidget::setupAsPlainEditor()
updateEditorInfoBar(this);
}
//
// TextEditorLinkLabel
//
TextEditorLinkLabel::TextEditorLinkLabel(QWidget *parent)
: QLabel(parent)
{
}
void TextEditorLinkLabel::setLink(TextEditorWidget::Link link)
{
m_link = link;
}
TextEditorWidget::Link TextEditorLinkLabel::link() const
{
return m_link;
}
void TextEditorLinkLabel::mousePressEvent(QMouseEvent *event)
{
if (event->button() == Qt::LeftButton)
m_dragStartPosition = event->pos();
}
void TextEditorLinkLabel::mouseMoveEvent(QMouseEvent *event)
{
if (!(event->buttons() & Qt::LeftButton))
return;
if ((event->pos() - m_dragStartPosition).manhattanLength() < QApplication::startDragDistance())
return;
auto data = new Utils::FileDropMimeData;
data->addFile(m_link.targetFileName, m_link.targetLine, m_link.targetColumn);
auto drag = new QDrag(this);
drag->setMimeData(data);
drag->exec(Qt::MoveAction);
}
void TextEditorLinkLabel::mouseReleaseEvent(QMouseEvent *event)
{
Q_UNUSED(event)
if (!m_link.hasValidTarget())
return;
Core::EditorManager::openEditorAt(m_link.targetFileName,
m_link.targetLine,
m_link.targetColumn);
}
//
// BaseTextEditorFactory
//
......
......@@ -45,6 +45,7 @@
#include <utils/uncommentselection.h>
#include <QLabel>
#include <QPlainTextEdit>
#include <functional>
......@@ -623,6 +624,24 @@ private:
friend class RefactorOverlay;
};
class TEXTEDITOR_EXPORT TextEditorLinkLabel : public QLabel
{
public:
TextEditorLinkLabel(QWidget *parent = 0);
void setLink(TextEditorWidget::Link link);
TextEditorWidget::Link link() const;
protected:
void mousePressEvent(QMouseEvent *event);
void mouseMoveEvent(QMouseEvent *event);
void mouseReleaseEvent(QMouseEvent *event);
private:
QPoint m_dragStartPosition;
TextEditorWidget::Link m_link;
};
class TEXTEDITOR_EXPORT TextEditorFactory : public Core::IEditorFactory
{
Q_OBJECT
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment