From b0503cabba718a093290dc7ade68a0f8e7d14a90 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Thu, 21 Mar 2013 13:41:44 +0100 Subject: [PATCH] Added drag and drop support. Implemented our own insertRows/deleteRows to avoid bug caused by default drag and drop behaviour of Qt https://bugreports.qt-project.org/browse/QTBUG-26229 https://bugreports.qt-project.org/browse/QTBUG-6679 p4#: 21028 --- .../ProjectDataModel/RimUiTreeModelPdm.cpp | 112 ++++++++++++++++-- .../ProjectDataModel/RimUiTreeModelPdm.h | 11 +- .../UserInterface/RIMainWindow.cpp | 8 +- cafUserInterface/cafUiTreeModelPdm.cpp | 8 +- cafUserInterface/cafUiTreeModelPdm.h | 6 +- 5 files changed, 122 insertions(+), 23 deletions(-) diff --git a/ApplicationCode/ProjectDataModel/RimUiTreeModelPdm.cpp b/ApplicationCode/ProjectDataModel/RimUiTreeModelPdm.cpp index ccff2720e6..35c24fc226 100644 --- a/ApplicationCode/ProjectDataModel/RimUiTreeModelPdm.cpp +++ b/ApplicationCode/ProjectDataModel/RimUiTreeModelPdm.cpp @@ -51,9 +51,9 @@ RimUiTreeModelPdm::RimUiTreeModelPdm(QObject* parent) } //-------------------------------------------------------------------------------------------------- -/// +/// TO BE DELETED //-------------------------------------------------------------------------------------------------- -bool RimUiTreeModelPdm::insertRows(int position, int rows, const QModelIndex &parent /*= QModelIndex()*/) +bool RimUiTreeModelPdm::insertRows_special(int position, int rows, const QModelIndex &parent /*= QModelIndex()*/) { caf::PdmUiTreeItem* parentItem = getTreeItemFromIndex(parent); @@ -126,7 +126,7 @@ bool RimUiTreeModelPdm::deletePropertyFilter(const QModelIndex& itemIndex) bool wasSomeFilterActive = propertyFilterCollection->hasActiveFilters(); // Remove Ui items pointing at the pdm object to delete - removeRow(itemIndex.row(), itemIndex.parent()); + removeRows_special(itemIndex.row(), 1, itemIndex.parent()); propertyFilterCollection->remove(propertyFilter); delete propertyFilter; @@ -166,7 +166,7 @@ bool RimUiTreeModelPdm::deleteRangeFilter(const QModelIndex& itemIndex) bool wasSomeFilterActive = rangeFilterCollection->hasActiveFilters(); // Remove Ui items pointing at the pdm object to delete - removeRow(itemIndex.row(), itemIndex.parent()); + removeRows_special(itemIndex.row(), 1, itemIndex.parent()); rangeFilterCollection->remove(rangeFilter); delete rangeFilter; @@ -200,7 +200,7 @@ bool RimUiTreeModelPdm::deleteReservoirView(const QModelIndex& itemIndex) CVF_ASSERT(reservoirView); // Remove Ui items pointing at the pdm object to delete - removeRow(itemIndex.row(), itemIndex.parent()); + removeRows_special(itemIndex.row(), 1, itemIndex.parent()); reservoirView->eclipseCase()->removeReservoirView(reservoirView); delete reservoirView; @@ -226,7 +226,7 @@ void RimUiTreeModelPdm::deleteReservoir(RimReservoir* reservoir) CVF_ASSERT(uiItem); // Remove Ui items pointing at the pdm object to delete - removeRow(mi.row(), mi.parent()); + removeRows_special(mi.row(), 1, mi.parent()); } RimProject* proj = RIApplication::instance()->project(); @@ -449,7 +449,7 @@ void RimUiTreeModelPdm::deleteInputProperty(const QModelIndex& itemIndex) if (!inputProperty) return; // Remove item from UI tree model before delete of project data structure - removeRow(itemIndex.row(), itemIndex.parent()); + removeRows_special(itemIndex.row(), 1, itemIndex.parent()); std::vector parentObjects; object->parentObjectsOfType(parentObjects); @@ -581,8 +581,8 @@ void RimUiTreeModelPdm::addObjects(const QModelIndex& itemIndex, caf::PdmObjectG caseCollection = rimReservoir->parentCaseCollection(); if (caseCollection) { - gridCaseGroup = caseCollection->parentCaseGroup(); - } + gridCaseGroup = caseCollection->parentCaseGroup(); + } } else { @@ -701,3 +701,97 @@ void RimUiTreeModelPdm::clearClipboard() } } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +Qt::DropActions RimUiTreeModelPdm::supportedDropActions() const +{ + return Qt::CopyAction | Qt::MoveAction; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +Qt::ItemFlags RimUiTreeModelPdm::flags(const QModelIndex &index) const +{ + Qt::ItemFlags defaultFlags = caf::UiTreeModelPdm::flags(index); + if (index.isValid()) + { + caf::PdmUiTreeItem* currentItem = getTreeItemFromIndex(index); + CVF_ASSERT(currentItem); + CVF_ASSERT(currentItem->dataObject().p()); + + if (dynamic_cast(currentItem->dataObject().p()) || + dynamic_cast(currentItem->dataObject().p())) + { + return Qt::ItemIsDropEnabled | defaultFlags; + } + else if (dynamic_cast(currentItem->dataObject().p())) + { + // TODO: Remember to handle reservoir holding the main grid + return Qt::ItemIsDragEnabled | defaultFlags; + } + } + + return defaultFlags; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimUiTreeModelPdm::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) +{ + const MimeDataWithIndexes* myMimeData = qobject_cast(data); + if (myMimeData && parent.isValid()) + { + caf::PdmObjectGroup pog; + + for (int i = 0; i < myMimeData->indexes().size(); i++) + { + QModelIndex mi = myMimeData->indexes().at(i); + caf::PdmUiTreeItem* currentItem = getTreeItemFromIndex(mi); + caf::PdmObject* pdmObj = currentItem->dataObject().p(); + + pog.objects().push_back(pdmObj); + } + + addObjects(parent, pog); + + if (action == Qt::MoveAction) + { + std::vector > typedObjects; + pog.objectsByType(&typedObjects); + + for (size_t i = 0; i < typedObjects.size(); i++) + { + RimReservoir* rimReservoir = typedObjects[i]; + deleteReservoir(rimReservoir); + } + } + + return true; + } + + return false; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QMimeData* RimUiTreeModelPdm::mimeData(const QModelIndexList &indexes) const +{ + MimeDataWithIndexes* myObj = new MimeDataWithIndexes(); + myObj->setIndexes(indexes); + return myObj; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QStringList RimUiTreeModelPdm::mimeTypes() const +{ + QStringList types; + types << MimeDataWithIndexes::formatName(); + return types; +} + diff --git a/ApplicationCode/ProjectDataModel/RimUiTreeModelPdm.h b/ApplicationCode/ProjectDataModel/RimUiTreeModelPdm.h index 59aabbc789..ece8c016dc 100644 --- a/ApplicationCode/ProjectDataModel/RimUiTreeModelPdm.h +++ b/ApplicationCode/ProjectDataModel/RimUiTreeModelPdm.h @@ -96,8 +96,9 @@ class RimUiTreeModelPdm : public caf::UiTreeModelPdm public: RimUiTreeModelPdm(QObject* parent); - // Overrides - virtual bool insertRows(int position, int rows, const QModelIndex &parent = QModelIndex()); + + // TO BE DELETED, NOT USED + virtual bool insertRows_special(int position, int rows, const QModelIndex &parent = QModelIndex()); // Special edit methods bool deleteRangeFilter(const QModelIndex& itemIndex); @@ -119,6 +120,12 @@ public: void updateScriptPaths(); + virtual Qt::DropActions supportedDropActions() const; + virtual Qt::ItemFlags flags(const QModelIndex &index) const; + virtual bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent); + virtual QMimeData * mimeData(const QModelIndexList &indexes) const; + virtual QStringList mimeTypes() const; + private slots: void slotRefreshScriptTree(QString path); void clearClipboard(); diff --git a/ApplicationCode/UserInterface/RIMainWindow.cpp b/ApplicationCode/UserInterface/RIMainWindow.cpp index 486696f477..90e87996b5 100644 --- a/ApplicationCode/UserInterface/RIMainWindow.cpp +++ b/ApplicationCode/UserInterface/RIMainWindow.cpp @@ -377,15 +377,11 @@ void RIMainWindow::createDockPanels() m_treeView->setModel(m_treeModelPdm); m_treeView->setSelectionMode(QAbstractItemView::ExtendedSelection); - // Must be enabled for drag and drop - /* - m_treeView->setSelectionMode(QAbstractItemView::SingleSelection); + // Drag and drop configuration m_treeView->setDragEnabled(true); m_treeView->viewport()->setAcceptDrops(true); m_treeView->setDropIndicatorShown(true); - m_treeView->setDragDropMode(QAbstractItemView::InternalMove); - */ - + m_treeView->setDragDropMode(QAbstractItemView::DragDrop); dockWidget->setWidget(m_treeView); diff --git a/cafUserInterface/cafUiTreeModelPdm.cpp b/cafUserInterface/cafUiTreeModelPdm.cpp index 85a5112cb5..f1195d9478 100644 --- a/cafUserInterface/cafUiTreeModelPdm.cpp +++ b/cafUserInterface/cafUiTreeModelPdm.cpp @@ -293,9 +293,9 @@ Qt::ItemFlags UiTreeModelPdm::flags(const QModelIndex &index) const } //-------------------------------------------------------------------------------------------------- -/// +/// TO BE DELETED //-------------------------------------------------------------------------------------------------- -bool UiTreeModelPdm::insertRows(int position, int rows, const QModelIndex &parent /*= QModelIndex()*/) +bool UiTreeModelPdm::insertRows_special(int position, int rows, const QModelIndex &parent /*= QModelIndex()*/) { PdmUiTreeItem* parentItem = getTreeItemFromIndex(parent); @@ -311,7 +311,7 @@ bool UiTreeModelPdm::insertRows(int position, int rows, const QModelIndex &paren //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool UiTreeModelPdm::removeRows(int position, int rows, const QModelIndex &parent /*= QModelIndex()*/) +bool UiTreeModelPdm::removeRows_special(int position, int rows, const QModelIndex &parent /*= QModelIndex()*/) { if (rows <= 0) return true; @@ -344,7 +344,7 @@ void UiTreeModelPdm::rebuildUiSubTree(PdmObject* root) QModelIndex item = getModelIndexFromPdmObject(root); if (item.isValid()) { - this->removeRows(0, rowCount(item), item); + this->removeRows_special(0, rowCount(item), item); PdmUiTreeItem* treeItem = getTreeItemFromIndex(item); diff --git a/cafUserInterface/cafUiTreeModelPdm.h b/cafUserInterface/cafUiTreeModelPdm.h index 0dfbf2593a..b5f8f7de4e 100644 --- a/cafUserInterface/cafUiTreeModelPdm.h +++ b/cafUserInterface/cafUiTreeModelPdm.h @@ -62,8 +62,10 @@ public: virtual Qt::ItemFlags flags(const QModelIndex &index) const; virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole); - virtual bool insertRows(int position, int rows, const QModelIndex &parent = QModelIndex()); - virtual bool removeRows(int position, int rows, const QModelIndex &parent = QModelIndex()); + // TO BE DELETED, NOT USED + virtual bool insertRows_special(int position, int rows, const QModelIndex &parent = QModelIndex()); + + virtual bool removeRows_special(int position, int rows, const QModelIndex &parent = QModelIndex()); protected: QModelIndex getModelIndexFromPdmObjectRecursive(const QModelIndex& root, const PdmObject * object) const;