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:
Mahmoud Badri
2022-05-10 01:10:22 +03:00
parent 57a69d9d0b
commit d4aa9eb0b7
8 changed files with 73 additions and 22 deletions

View File

@@ -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);

View File

@@ -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)
{ {

View File

@@ -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);

View File

@@ -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;

View File

@@ -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();

View File

@@ -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));

View File

@@ -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"));

View File

@@ -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();