forked from qt-creator/qt-creator
QmlDesigner: Integrate drag and drop into the model/views system
so that any view can easily gets notified when a drag in another view is started/ended. This allows a view to show a highlight when a valid drag is started in another view without coupling the 2 views. Change-Id: I030d3dfe23ee06e2afdc0e4bbffc0b8d0c59f2f8 Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io> Reviewed-by: <github-actions-qt-creator@cristianadam.eu> Reviewed-by: Miikka Heikkinen <miikka.heikkinen@qt.io> Reviewed-by: Samuel Ghinet <samuel.ghinet@qt.io>
This commit is contained in:
@@ -40,7 +40,6 @@
|
|||||||
#include "modelnodeoperations.h"
|
#include "modelnodeoperations.h"
|
||||||
#include <metainfo.h>
|
#include <metainfo.h>
|
||||||
#include <model.h>
|
#include <model.h>
|
||||||
#include <navigatorwidget.h>
|
|
||||||
#include <rewritingexception.h>
|
#include <rewritingexception.h>
|
||||||
#include <qmldesignerconstants.h>
|
#include <qmldesignerconstants.h>
|
||||||
#include <qmldesignerplugin.h>
|
#include <qmldesignerplugin.h>
|
||||||
@@ -89,6 +88,9 @@ static QString propertyEditorResourcesPath()
|
|||||||
|
|
||||||
bool ItemLibraryWidget::eventFilter(QObject *obj, QEvent *event)
|
bool ItemLibraryWidget::eventFilter(QObject *obj, QEvent *event)
|
||||||
{
|
{
|
||||||
|
auto document = QmlDesignerPlugin::instance()->currentDesignDocument();
|
||||||
|
Model *model = document ? document->documentModel() : nullptr;
|
||||||
|
|
||||||
if (event->type() == QEvent::FocusOut) {
|
if (event->type() == QEvent::FocusOut) {
|
||||||
if (obj == m_itemsWidget.data())
|
if (obj == m_itemsWidget.data())
|
||||||
QMetaObject::invokeMethod(m_itemsWidget->rootObject(), "closeContextMenu");
|
QMetaObject::invokeMethod(m_itemsWidget->rootObject(), "closeContextMenu");
|
||||||
@@ -115,33 +117,19 @@ bool ItemLibraryWidget::eventFilter(QObject *obj, QEvent *event)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
QWidget *view = QmlDesignerPlugin::instance()->viewManager().widget("Navigator");
|
|
||||||
if (view) {
|
if (model) {
|
||||||
NavigatorWidget *navView = qobject_cast<NavigatorWidget *>(view);
|
model->startDrag(m_itemLibraryModel->getMimeData(entry),
|
||||||
if (navView) {
|
Utils::StyleHelper::dpiSpecificImageFile(entry.libraryEntryIconPath()));
|
||||||
navView->setDragType(entry.typeName());
|
|
||||||
navView->update();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
auto drag = new QDrag(this);
|
|
||||||
drag->setPixmap(Utils::StyleHelper::dpiSpecificImageFile(entry.libraryEntryIconPath()));
|
|
||||||
drag->setMimeData(m_itemLibraryModel->getMimeData(entry));
|
|
||||||
drag->exec();
|
|
||||||
drag->deleteLater();
|
|
||||||
|
|
||||||
m_itemToDrag = {};
|
m_itemToDrag = {};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (event->type() == QMouseEvent::MouseButtonRelease) {
|
} else if (event->type() == QMouseEvent::MouseButtonRelease) {
|
||||||
m_itemToDrag = {};
|
m_itemToDrag = {};
|
||||||
QWidget *view = QmlDesignerPlugin::instance()->viewManager().widget("Navigator");
|
if (model)
|
||||||
if (view) {
|
model->endDrag();
|
||||||
NavigatorWidget *navView = qobject_cast<NavigatorWidget *>(view);
|
|
||||||
if (navView) {
|
|
||||||
navView->setDragType("");
|
|
||||||
navView->update();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return QObject::eventFilter(obj, event);
|
return QObject::eventFilter(obj, event);
|
||||||
|
@@ -36,6 +36,7 @@
|
|||||||
#include <bindingproperty.h>
|
#include <bindingproperty.h>
|
||||||
#include <designmodecontext.h>
|
#include <designmodecontext.h>
|
||||||
#include <designersettings.h>
|
#include <designersettings.h>
|
||||||
|
#include <itemlibraryinfo.h>
|
||||||
#include <nodeproperty.h>
|
#include <nodeproperty.h>
|
||||||
#include <nodelistproperty.h>
|
#include <nodelistproperty.h>
|
||||||
#include <variantproperty.h>
|
#include <variantproperty.h>
|
||||||
@@ -57,8 +58,9 @@
|
|||||||
#include <utils/stylehelper.h>
|
#include <utils/stylehelper.h>
|
||||||
|
|
||||||
#include <QHeaderView>
|
#include <QHeaderView>
|
||||||
#include <QTimer>
|
#include <QMimeData>
|
||||||
#include <QPixmap>
|
#include <QPixmap>
|
||||||
|
#include <QTimer>
|
||||||
|
|
||||||
static inline void setScenePos(const QmlDesigner::ModelNode &modelNode,const QPointF &pos)
|
static inline void setScenePos(const QmlDesigner::ModelNode &modelNode,const QPointF &pos)
|
||||||
{
|
{
|
||||||
@@ -264,6 +266,25 @@ void NavigatorView::bindingPropertiesChanged(const QList<BindingProperty> & prop
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NavigatorView::dragStarted(QMimeData *mimeData)
|
||||||
|
{
|
||||||
|
if (mimeData->hasFormat("application/vnd.bauhaus.itemlibraryinfo")) {
|
||||||
|
QByteArray data = mimeData->data("application/vnd.bauhaus.itemlibraryinfo");
|
||||||
|
QDataStream stream(data);
|
||||||
|
ItemLibraryEntry itemLibraryEntry;
|
||||||
|
stream >> itemLibraryEntry;
|
||||||
|
|
||||||
|
m_widget->setDragType(itemLibraryEntry.typeName());
|
||||||
|
m_widget->update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void NavigatorView::dragEnded()
|
||||||
|
{
|
||||||
|
m_widget->setDragType("");
|
||||||
|
m_widget->update();
|
||||||
|
}
|
||||||
|
|
||||||
void NavigatorView::customNotification(const AbstractView *view, const QString &identifier,
|
void NavigatorView::customNotification(const AbstractView *view, const QString &identifier,
|
||||||
const QList<ModelNode> &nodeList, const QList<QVariant> &data)
|
const QList<ModelNode> &nodeList, const QList<QVariant> &data)
|
||||||
{
|
{
|
||||||
|
@@ -92,6 +92,9 @@ public:
|
|||||||
|
|
||||||
void bindingPropertiesChanged(const QList<BindingProperty> &propertyList, PropertyChangeFlags) override;
|
void bindingPropertiesChanged(const QList<BindingProperty> &propertyList, PropertyChangeFlags) override;
|
||||||
|
|
||||||
|
void dragStarted(QMimeData *mimeData) override;
|
||||||
|
void dragEnded() override;
|
||||||
|
|
||||||
void customNotification(const AbstractView *view, const QString &identifier, const QList<ModelNode> &nodeList, const QList<QVariant> &data) override;
|
void customNotification(const AbstractView *view, const QString &identifier, const QList<ModelNode> &nodeList, const QList<QVariant> &data) override;
|
||||||
|
|
||||||
void handleChangedExport(const ModelNode &modelNode, bool exported);
|
void handleChangedExport(const ModelNode &modelNode, bool exported);
|
||||||
|
@@ -254,6 +254,9 @@ public:
|
|||||||
virtual void updateImport3DSupport(const QVariantMap &supportMap);
|
virtual void updateImport3DSupport(const QVariantMap &supportMap);
|
||||||
virtual void modelNodePreviewPixmapChanged(const ModelNode &node, const QPixmap &pixmap);
|
virtual void modelNodePreviewPixmapChanged(const ModelNode &node, const QPixmap &pixmap);
|
||||||
|
|
||||||
|
virtual void dragStarted(QMimeData *mimeData);
|
||||||
|
virtual void dragEnded();
|
||||||
|
|
||||||
void changeRootNodeType(const TypeName &type, int majorVersion, int minorVersion);
|
void changeRootNodeType(const TypeName &type, int majorVersion, int minorVersion);
|
||||||
|
|
||||||
NodeInstanceView *nodeInstanceView() const;
|
NodeInstanceView *nodeInstanceView() const;
|
||||||
|
@@ -129,6 +129,9 @@ public:
|
|||||||
QString generateNewId(const QString &prefixName) const;
|
QString generateNewId(const QString &prefixName) const;
|
||||||
QString generateNewId(const QString &prefixName, const QString &fallbackPrefix) const;
|
QString generateNewId(const QString &prefixName, const QString &fallbackPrefix) const;
|
||||||
|
|
||||||
|
void startDrag(QMimeData *mimeData, const QString iconPath = {});
|
||||||
|
void endDrag();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Model();
|
Model();
|
||||||
|
|
||||||
|
@@ -398,6 +398,9 @@ void AbstractView::modelNodePreviewPixmapChanged(const ModelNode & /*node*/, con
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AbstractView::dragStarted(QMimeData *mimeData) {}
|
||||||
|
void AbstractView::dragEnded() {}
|
||||||
|
|
||||||
QList<ModelNode> AbstractView::toModelNodeList(const QList<Internal::InternalNode::Pointer> &nodeList) const
|
QList<ModelNode> AbstractView::toModelNodeList(const QList<Internal::InternalNode::Pointer> &nodeList) const
|
||||||
{
|
{
|
||||||
return QmlDesigner::toModelNodeList(nodeList, const_cast<AbstractView*>(this));
|
return QmlDesigner::toModelNodeList(nodeList, const_cast<AbstractView*>(this));
|
||||||
|
@@ -67,6 +67,7 @@
|
|||||||
|
|
||||||
#include <utils/algorithm.h>
|
#include <utils/algorithm.h>
|
||||||
|
|
||||||
|
#include <QDrag>
|
||||||
#include <QRegularExpression>
|
#include <QRegularExpression>
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -588,6 +589,16 @@ void ModelPrivate::notifyImport3DSupportChanged(const QVariantMap &supportMap)
|
|||||||
notifyInstanceChanges([&](AbstractView *view) { view->updateImport3DSupport(supportMap); });
|
notifyInstanceChanges([&](AbstractView *view) { view->updateImport3DSupport(supportMap); });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ModelPrivate::notifyDragStarted(QMimeData *mimeData)
|
||||||
|
{
|
||||||
|
notifyInstanceChanges([&](AbstractView *view) { view->dragStarted(mimeData); });
|
||||||
|
}
|
||||||
|
|
||||||
|
void ModelPrivate::notifyDragEnded()
|
||||||
|
{
|
||||||
|
notifyInstanceChanges([&](AbstractView *view) { view->dragEnded(); });
|
||||||
|
}
|
||||||
|
|
||||||
void ModelPrivate::notifyRewriterBeginTransaction()
|
void ModelPrivate::notifyRewriterBeginTransaction()
|
||||||
{
|
{
|
||||||
notifyNodeInstanceViewLast([&](AbstractView *view) { view->rewriterBeginTransaction(); });
|
notifyNodeInstanceViewLast([&](AbstractView *view) { view->rewriterBeginTransaction(); });
|
||||||
@@ -1492,6 +1503,22 @@ QString Model::generateNewId(const QString &prefixName, const QString &fallbackP
|
|||||||
return newId;
|
return newId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Model::startDrag(QMimeData *mimeData, const QString iconPath)
|
||||||
|
{
|
||||||
|
d->notifyDragStarted(mimeData);
|
||||||
|
|
||||||
|
auto drag = new QDrag(this);
|
||||||
|
drag->setPixmap(iconPath);
|
||||||
|
drag->setMimeData(mimeData);
|
||||||
|
drag->exec();
|
||||||
|
drag->deleteLater();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Model::endDrag()
|
||||||
|
{
|
||||||
|
d->notifyDragEnded();
|
||||||
|
}
|
||||||
|
|
||||||
QString Model::generateNewId(const QString &prefixName) const
|
QString Model::generateNewId(const QString &prefixName) const
|
||||||
{
|
{
|
||||||
return generateNewId(prefixName, QStringLiteral("element"));
|
return generateNewId(prefixName, QStringLiteral("element"));
|
||||||
|
@@ -183,6 +183,9 @@ public:
|
|||||||
void notifyModelNodePreviewPixmapChanged(const ModelNode &node, const QPixmap &pixmap);
|
void notifyModelNodePreviewPixmapChanged(const ModelNode &node, const QPixmap &pixmap);
|
||||||
void notifyImport3DSupportChanged(const QVariantMap &supportMap);
|
void notifyImport3DSupportChanged(const QVariantMap &supportMap);
|
||||||
|
|
||||||
|
void notifyDragStarted(QMimeData *mimeData);
|
||||||
|
void notifyDragEnded();
|
||||||
|
|
||||||
void setDocumentMessages(const QList<DocumentMessage> &errors, const QList<DocumentMessage> &warnings);
|
void setDocumentMessages(const QList<DocumentMessage> &errors, const QList<DocumentMessage> &warnings);
|
||||||
|
|
||||||
void notifyRewriterBeginTransaction();
|
void notifyRewriterBeginTransaction();
|
||||||
|
Reference in New Issue
Block a user