From 7dd1cf4a073190e263782c716f43e4d684a47d75 Mon Sep 17 00:00:00 2001
From: Gennady Pospelov <g.pospelov@fz-juelich.de>
Date: Mon, 16 May 2016 16:16:52 +0200
Subject: [PATCH] First drag/drop attempts in FitParameterAbsModel

---
 GUI/coregui/Models/FitParameterAbsModel.cpp   | 71 +++++++++++++++++++
 GUI/coregui/Models/FitParameterAbsModel.h     | 31 ++++++--
 .../Views/FitWidgets/FitParametersWidget.cpp  |  5 +-
 3 files changed, 102 insertions(+), 5 deletions(-)

diff --git a/GUI/coregui/Models/FitParameterAbsModel.cpp b/GUI/coregui/Models/FitParameterAbsModel.cpp
index 13474a29395..ba97395a788 100644
--- a/GUI/coregui/Models/FitParameterAbsModel.cpp
+++ b/GUI/coregui/Models/FitParameterAbsModel.cpp
@@ -20,8 +20,12 @@
 #include "SessionModel.h"
 #include "JobModel.h"
 #include <QColor>
+#include <QMimeData>
 #include <QDebug>
 
+const QString FitParameterAbsModel::MIME_TYPE = "application/org.bornagainproject.fittinglink";
+
+
 FitParameterAbsModel::FitParameterAbsModel(FitParameterContainerItem *fitParContainer, QObject *parent)
     : QAbstractItemModel(parent)
     , m_root_item(fitParContainer)
@@ -50,7 +54,15 @@ Qt::ItemFlags FitParameterAbsModel::flags(const QModelIndex &index) const
     if(SessionItem *item = itemForIndex(index)) {
 //        if(item->isEnabled()) returnVal |= Qt::ItemIsEnabled;
         if(item->isEditable()) returnVal |= Qt::ItemIsEditable;
+        if(item->parent()->modelType() == Constants::FitParameterLinkType && index.column() == 0) {
+            returnVal |= Qt::ItemIsDragEnabled;
+        }
+        if(item->modelType() == Constants::FitParameterType) {
+            returnVal |= Qt::ItemIsDropEnabled;
+        }
+
     }
+
     return returnVal;
 
 //    Qt::ItemFlags returnVal = Qt::ItemIsEnabled | Qt::ItemIsSelectable;
@@ -196,6 +208,65 @@ bool FitParameterAbsModel::setData(const QModelIndex &index, const QVariant &val
     return false;
 }
 
+QStringList FitParameterAbsModel::mimeTypes() const
+{
+    QStringList types;
+    types << FitParameterAbsModel::MIME_TYPE;
+    return types;
+}
+
+QMimeData *FitParameterAbsModel::mimeData(const QModelIndexList &indexes) const
+{
+    qDebug() << "FitParameterAbsModel::mimeData" << indexes;
+    QMimeData *mimeData = new QMimeData();
+    QModelIndex index = indexes.first();
+    if (index.isValid()) {
+        if(SessionItem *item = itemForIndex(index)) {
+            QString path = item->value().toString();
+            mimeData->setData(MIME_TYPE, path.toLatin1());
+            qDebug() << "       FitParameterAbsModel::mimeData" << path;
+
+        }
+//        QString path = getPathFromIndex(index);
+//        path = path.append("#%1").arg(itemFromIndex(index.sibling(index.row(), 1))
+//                                      ->data(Qt::EditRole).toDouble());
+    }
+    return mimeData;
+}
+
+bool FitParameterAbsModel::canDropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) const
+{
+    Q_UNUSED(action);
+    Q_UNUSED(row);
+    Q_UNUSED(parent);
+//    if (column > 0)
+//        return false;
+    QString link = QString::fromLatin1(data->data(MIME_TYPE)).split("#")[0];
+    qDebug() << "FitParameterAbsModel::canDropMimeData" << "row:" << row << "column:" << column << "parent:" << parent << link;
+
+    if(parent.isValid()) {
+
+    qDebug() << "!!! true";
+    return true;
+
+    }
+    return false;
+//    QString link = QString::fromLatin1(data->data(ObsoleteFitParameterWidget::MIME_TYPE)).split("#")[0];
+//    QModelIndex cur = itemForLink(link);
+//    return !cur.isValid();
+
+}
+
+bool FitParameterAbsModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent)
+{
+//    if (action == Qt::IgnoreAction) return true;
+//    if (column > 0) return true;
+
+    qDebug() << "FitParameterAbsModel::dropMimeData row:" << row << "column:" << column << "parent:" << parent << "mime:" <<  QString::fromLatin1(data->data(MIME_TYPE));
+
+    return true;
+}
+
 QVariant FitParameterAbsModel::headerData(int section, Qt::Orientation orientation, int role) const
 {
     if (role == Qt::DisplayRole && orientation == Qt::Horizontal) {
diff --git a/GUI/coregui/Models/FitParameterAbsModel.h b/GUI/coregui/Models/FitParameterAbsModel.h
index b0259c9d884..e787e10c9e3 100644
--- a/GUI/coregui/Models/FitParameterAbsModel.h
+++ b/GUI/coregui/Models/FitParameterAbsModel.h
@@ -32,20 +32,33 @@ class BA_CORE_API_ FitParameterAbsModel : public QAbstractItemModel
     Q_OBJECT
 
 public:
+    static const QString MIME_TYPE;
+
     explicit FitParameterAbsModel(FitParameterContainerItem *fitParContainer, QObject *parent = 0);
 
     enum EColumn {PAR_NAME, PAR_TYPE, PAR_VALUE, PAR_MIN, PAR_MAX, MAX_COLUMNS}; // NEW column usage
 
 
     Qt::ItemFlags flags(const QModelIndex & index) const Q_DECL_OVERRIDE;
-    virtual QModelIndex index(int row, int column, const QModelIndex &parent) const;
-    virtual QModelIndex parent(const QModelIndex &child) const;
-    virtual int rowCount(const QModelIndex &parent) const;
-    virtual int columnCount(const QModelIndex &parent) const;
+    QModelIndex index(int row, int column, const QModelIndex &parent) const;
+    QModelIndex parent(const QModelIndex &child) const;
+    int rowCount(const QModelIndex &parent) const;
+    int columnCount(const QModelIndex &parent) const;
     QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const Q_DECL_OVERRIDE;
     bool setData(const QModelIndex &index, const QVariant &value, int role) Q_DECL_OVERRIDE;
+
+    QStringList mimeTypes() const Q_DECL_OVERRIDE;
+//    Qt::DropActions supportedDragActions() const;
+//    Qt::DropActions supportedDropActions() const;
+    QMimeData *mimeData(const QModelIndexList &indexes) const;
+    bool canDropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column,
+                             const QModelIndex &parent) const Q_DECL_OVERRIDE;
+    bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent)  Q_DECL_OVERRIDE;
+
+
     QVariant headerData(int section, Qt::Orientation orientation, int role) const Q_DECL_OVERRIDE;
 
+
     QModelIndex indexOfItem(SessionItem *item) const;
     SessionItem *itemForIndex(const QModelIndex &index) const;
 
@@ -62,5 +75,15 @@ private:
     QMap<int, QString> m_columnNames;
 };
 
+//inline Qt::DropActions FitParameterAbsModel::supportedDragActions() const
+//{
+//    return Qt::MoveAction;
+//}
+
+//inline Qt::DropActions FitParameterAbsModel::supportedDropActions() const
+//{
+//    return Qt::MoveAction;
+//}
+
 
 #endif
diff --git a/GUI/coregui/Views/FitWidgets/FitParametersWidget.cpp b/GUI/coregui/Views/FitWidgets/FitParametersWidget.cpp
index e047f6f0919..3778d2a20a8 100644
--- a/GUI/coregui/Views/FitWidgets/FitParametersWidget.cpp
+++ b/GUI/coregui/Views/FitWidgets/FitParametersWidget.cpp
@@ -53,13 +53,16 @@ FitParametersWidget::FitParametersWidget(QWidget *parent)
     setLayout(layout);
     init_actions();
 
-    m_treeView->setSelectionMode(QAbstractItemView::ExtendedSelection);
+//    m_treeView->setSelectionMode(QAbstractItemView::SingleSelection);
     m_treeView->setSelectionBehavior(QAbstractItemView::SelectRows);
     m_treeView->setContextMenuPolicy(Qt::CustomContextMenu);
     m_treeView->setItemDelegate(m_delegate);
     connect(m_treeView, SIGNAL(customContextMenuRequested(const QPoint &)),
             this, SLOT(onFitParameterTreeContextMenu(const QPoint &)));
 
+    m_treeView->setDragEnabled(true);
+    m_treeView->setDragDropMode(QAbstractItemView::DragDrop);
+
     m_treeView->installEventFilter(m_keyboardFilter);
 
 }
-- 
GitLab