From 50d0358c0cb71da757a6bbb067c102cc52b2b49d Mon Sep 17 00:00:00 2001 From: Walter Van Herck <w.van.herck@fz-juelich.de> Date: Mon, 31 Mar 2014 10:47:47 +0200 Subject: [PATCH] Smarter drag and drop in treeview (GUI indicates permitted drop operations) --- GUI/coregui/Models/SessionModel.cpp | 24 +++++---- GUI/coregui/Models/SessionModel.h | 8 +++ .../SampleDesigner/ItemTreeView.cpp | 51 +++++++++++++++++++ .../Components/SampleDesigner/ItemTreeView.h | 20 ++++++++ GUI/coregui/Views/SampleViewComponents.cpp | 4 +- GUI/coregui/Views/SampleViewComponents.h | 4 +- GUI/coregui/utils/GUIHelpers.h | 2 +- 7 files changed, 99 insertions(+), 14 deletions(-) create mode 100644 GUI/coregui/Views/Components/SampleDesigner/ItemTreeView.cpp create mode 100644 GUI/coregui/Views/Components/SampleDesigner/ItemTreeView.h diff --git a/GUI/coregui/Models/SessionModel.cpp b/GUI/coregui/Models/SessionModel.cpp index bf99e2b03dd..e7594f63917 100644 --- a/GUI/coregui/Models/SessionModel.cpp +++ b/GUI/coregui/Models/SessionModel.cpp @@ -27,7 +27,6 @@ enum Column { ModelType, MaxColumns }; -const QString MimeType = "application/org.bornagainproject.xml.item.z"; } SessionModel::SessionModel(QObject *parent) @@ -46,8 +45,14 @@ Qt::ItemFlags SessionModel::flags(const QModelIndex &index) const Qt::ItemFlags result_flags = QAbstractItemModel::flags(index); if (index.isValid()) { result_flags |= Qt::ItemIsSelectable|Qt::ItemIsEnabled - |Qt::ItemIsEditable|Qt::ItemIsDragEnabled - |Qt::ItemIsDropEnabled; + |Qt::ItemIsEditable|Qt::ItemIsDragEnabled; + QList<QString> acceptable_child_items = getAcceptableChildItems(index); + if (acceptable_child_items.contains(m_dragged_item_type)) { + result_flags |= Qt::ItemIsDropEnabled; + } + } + else { + result_flags |= Qt::ItemIsDropEnabled; } return result_flags; } @@ -154,7 +159,7 @@ bool SessionModel::removeRows(int row, int count, const QModelIndex &parent) QStringList SessionModel::mimeTypes() const { - return QStringList() << MimeType; + return QStringList() << SessionXML::MimeType; } QMimeData *SessionModel::mimeData(const QModelIndexList &indices) const @@ -165,7 +170,8 @@ QMimeData *SessionModel::mimeData(const QModelIndexList &indices) const QByteArray xml_data; QXmlStreamWriter writer(&xml_data); writeItemAndChildItems(&writer, item); - mime_data->setData(MimeType, qCompress(xml_data, MaxCompression)); + mime_data->setData(SessionXML::MimeType, + qCompress(xml_data, MaxCompression)); return mime_data; } return 0; @@ -178,10 +184,10 @@ bool SessionModel::canDropMimeData(const QMimeData *data, Qt::DropAction action, (void)row; if (action == Qt::IgnoreAction) return true; if (action != Qt::MoveAction || column > 0 || !data - || !data->hasFormat(MimeType)) return false; + || !data->hasFormat(SessionXML::MimeType)) return false; if (!parent.isValid()) return true; QList<QString> acceptable_child_items = getAcceptableChildItems(parent); - QByteArray xml_data = qUncompress(data->data(MimeType)); + QByteArray xml_data = qUncompress(data->data(SessionXML::MimeType)); QXmlStreamReader reader(xml_data); while (!reader.atEnd()) { reader.readNext(); @@ -201,10 +207,10 @@ bool SessionModel::dropMimeData(const QMimeData *data, Qt::DropAction action, { if (action == Qt::IgnoreAction) return true; if (action != Qt::MoveAction || column > 0 || !data - || !data->hasFormat(MimeType)) return false; + || !data->hasFormat(SessionXML::MimeType)) return false; if (!canDropMimeData(data, action, row, column, parent)) return false; if (ParameterizedItem *item = itemForIndex(parent)) { - QByteArray xml_data = qUncompress(data->data(MimeType)); + QByteArray xml_data = qUncompress(data->data(SessionXML::MimeType)); QXmlStreamReader reader(xml_data); if (row == -1) row = item->childItemCount(); beginInsertRows(parent, row, row); diff --git a/GUI/coregui/Models/SessionModel.h b/GUI/coregui/Models/SessionModel.h index c9fa1d7d6d2..408fb39d252 100644 --- a/GUI/coregui/Models/SessionModel.h +++ b/GUI/coregui/Models/SessionModel.h @@ -23,6 +23,8 @@ #include "ParameterizedItem.h" namespace SessionXML { +const QString MimeType = "application/org.bornagainproject.xml.item.z"; + const QString ItemTag("Item"); const QString ModelTypeAttribute("ModelType"); const QString ItemNameAttribute("ItemName"); @@ -82,6 +84,11 @@ public: void load(const QString &filename=QString()); void save(const QString &filename=QString()); + // Sets mimedata pointer of item being dragged + void setDraggedItemType(const QString& type) { + m_dragged_item_type = type; + } + private: ParameterizedItem *insertNewItem(QString model_type, ParameterizedItem *parent, @@ -96,6 +103,7 @@ private: const char *property_name) const; QString m_filename; ParameterizedItem *m_root_item; + QString m_dragged_item_type; }; #endif // SESSIONMODEL_H diff --git a/GUI/coregui/Views/Components/SampleDesigner/ItemTreeView.cpp b/GUI/coregui/Views/Components/SampleDesigner/ItemTreeView.cpp new file mode 100644 index 00000000000..ddec416d054 --- /dev/null +++ b/GUI/coregui/Views/Components/SampleDesigner/ItemTreeView.cpp @@ -0,0 +1,51 @@ +// ************************************************************************** // +// +// BornAgain: simulate and fit scattering at grazing incidence +// +//! @file Views/SampleDesigner/ItemTreeView.cpp +//! @brief Implements class ItemTreeView. +//! +//! @homepage http://apps.jcns.fz-juelich.de/BornAgain +//! @license GNU General Public License v3 or higher (see COPYING) +//! @copyright Forschungszentrum Jülich GmbH 2013 +//! @authors Scientific Computing Group at MLZ Garching +//! @authors C. Durniak, G. Pospelov, W. Van Herck, J. Wuttke +// +// ************************************************************************** // + +#include "ItemTreeView.h" +#include "SessionModel.h" +#include "GUIHelpers.h" + +#include <QDragMoveEvent> +#include <QMimeData> + +ItemTreeView::ItemTreeView(QWidget *parent) + : QTreeView(parent) +{ +} + +ItemTreeView::~ItemTreeView() +{ +} + +void ItemTreeView::dragMoveEvent(QDragMoveEvent *event) +{ + QTreeView::dragMoveEvent(event); + SessionModel *model = static_cast<SessionModel *>(this->model()); + model->setDraggedItemType(QString()); + QByteArray xml_data = qUncompress( + event->mimeData()->data(SessionXML::MimeType)); + QXmlStreamReader reader(xml_data); + while (!reader.atEnd()) { + reader.readNext(); + if (reader.isStartElement()) { + if (reader.name() == SessionXML::ItemTag) { + const QString model_type = reader.attributes() + .value(SessionXML::ModelTypeAttribute).toString(); + model->setDraggedItemType(model_type); + break; + } + } + } +} diff --git a/GUI/coregui/Views/Components/SampleDesigner/ItemTreeView.h b/GUI/coregui/Views/Components/SampleDesigner/ItemTreeView.h new file mode 100644 index 00000000000..216b50aaddd --- /dev/null +++ b/GUI/coregui/Views/Components/SampleDesigner/ItemTreeView.h @@ -0,0 +1,20 @@ +#ifndef ITEMTREEVIEW_H +#define ITEMTREEVIEW_H + +#include <QTreeView> + +class ItemTreeView : public QTreeView +{ + Q_OBJECT +public: + explicit ItemTreeView(QWidget *parent=0); + ~ItemTreeView(); + +protected: +#ifndef QT_NO_DRAGANDDROP + void dragMoveEvent(QDragMoveEvent *event); +#endif +}; + + +#endif // ITEMTREEVIEW_H diff --git a/GUI/coregui/Views/SampleViewComponents.cpp b/GUI/coregui/Views/SampleViewComponents.cpp index 9bc098aba65..dfbbf816e2d 100644 --- a/GUI/coregui/Views/SampleViewComponents.cpp +++ b/GUI/coregui/Views/SampleViewComponents.cpp @@ -41,10 +41,10 @@ SamplePropertyEditor *SampleViewComponents::createPropertyEditor( return new SamplePropertyEditor(selection_model, parent); } -QTreeView *SampleViewComponents::createTreeView( +ItemTreeView *SampleViewComponents::createTreeView( SessionModel *session_model, QWidget *parent) { - QTreeView *tree_view = new QTreeView(parent); + ItemTreeView *tree_view = new ItemTreeView(parent); tree_view->setModel(session_model); tree_view->setAllColumnsShowFocus(true); tree_view->setWindowTitle(QString("Object Tree View")); diff --git a/GUI/coregui/Views/SampleViewComponents.h b/GUI/coregui/Views/SampleViewComponents.h index b9c34a37304..dfaf98a5913 100644 --- a/GUI/coregui/Views/SampleViewComponents.h +++ b/GUI/coregui/Views/SampleViewComponents.h @@ -2,7 +2,7 @@ #define SAMPLEVIEWCOMPONENTS_H #include <QWidget> -#include <QTreeView> +#include "ItemTreeView.h" #include "widgetbox.h" #include "SamplePropertyEditor.h" @@ -45,7 +45,7 @@ public: SampleDesignerInterface *core, QWidget *parent); static SamplePropertyEditor *createPropertyEditor( QItemSelectionModel *selection_model, QWidget *parent); - static QTreeView *createTreeView( + static ItemTreeView *createTreeView( SessionModel *session_model, QWidget *parent); static SampleInfoStreamInterface *createInfoStream(QWidget *parent); }; diff --git a/GUI/coregui/utils/GUIHelpers.h b/GUI/coregui/utils/GUIHelpers.h index 4222f44d14c..af9d116013e 100644 --- a/GUI/coregui/utils/GUIHelpers.h +++ b/GUI/coregui/utils/GUIHelpers.h @@ -46,7 +46,7 @@ bool question(QWidget *parent, const QString &title, const QString &noText=QObject::tr("&No")); bool okToDelete(QWidget *parent, const QString &title, const QString &text, const QString &detailedText=QString()); -}; +} #endif // GUIHELPERS_H -- GitLab