diff --git a/NEWS.md b/NEWS.md
index 3dfdf846..c2d73924 100644
--- a/NEWS.md
+++ b/NEWS.md
@@ -6,6 +6,8 @@ Version 0.7.2
- enhancement: icons in project view
- fix: sometimes option widget will show confirm dialog even not changed
- enhancement: only editor area will receive file drop events
+ - enhancement: change project file's folder by drag and drop in the project view
+ - enhancement: open project file by drag it to the editor area
Version 0.7.1
- fix: can't add bookmark at a breakpoint line
diff --git a/RedPandaIDE/mainwindow.ui b/RedPandaIDE/mainwindow.ui
index e512cfe1..02dfdd4d 100644
--- a/RedPandaIDE/mainwindow.ui
+++ b/RedPandaIDE/mainwindow.ui
@@ -126,7 +126,7 @@
Qt::MoveAction
- QAbstractItemView::ExtendedSelection
+ QAbstractItemView::SingleSelection
QAbstractItemView::SelectRows
diff --git a/RedPandaIDE/project.cpp b/RedPandaIDE/project.cpp
index bf6eb8c2..12ba63dc 100644
--- a/RedPandaIDE/project.cpp
+++ b/RedPandaIDE/project.cpp
@@ -18,6 +18,7 @@
#include
#include
#include
+#include
#include "settings.h"
#include
@@ -1779,18 +1780,7 @@ QModelIndex ProjectModel::parent(const QModelIndex &child) const
FolderNode * node = static_cast(child.internalPointer());
if (!node)
return QModelIndex();
- PFolderNode parent = node->parent.lock();
- if (!parent) // root node
- return QModelIndex();
- PFolderNode grand = parent->parent.lock();
- if (!grand) {
- return createIndex(0,0,parent.get());
- }
-
- int row = grand->children.indexOf(parent);
- if (row<0)
- return QModelIndex();
- return createIndex(row,0,parent.get());
+ return getParentIndex(node);
}
int ProjectModel::rowCount(const QModelIndex &parent) const
@@ -1841,7 +1831,7 @@ Qt::ItemFlags ProjectModel::flags(const QModelIndex &index) const
if (!p)
return Qt::NoItemFlags;
if (p==mProject->node().get())
- return Qt::ItemIsEnabled;
+ return Qt::ItemIsEnabled | Qt::ItemIsDropEnabled;
Qt::ItemFlags flags = Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled;
if (p->unitIndex<0)
flags.setFlag(Qt::ItemIsDropEnabled);
@@ -1942,40 +1932,146 @@ bool ProjectModel::setData(const QModelIndex &index, const QVariant &value, int
return false;
}
-bool ProjectModel::canDropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) const
+QModelIndex ProjectModel::getParentIndex(FolderNode * node) const
{
- if (action != Qt::MoveAction)
- return false;
- QModelIndex idx;
- if (row >= rowCount(parent) || row < 0) {
- qDebug()<<"above/below";
- idx = parent;
- } else {
- idx= index(row,column,parent);
+ PFolderNode parent = node->parent.lock();
+ if (!parent) // root node
+ return QModelIndex();
+ PFolderNode grand = parent->parent.lock();
+ if (!grand) {
+ return createIndex(0,0,parent.get());
}
- if (!idx.isValid())
+
+ int row = grand->children.indexOf(parent);
+ if (row<0)
+ return QModelIndex();
+ return createIndex(row,0,parent.get());
+}
+
+bool ProjectModel::canDropMimeData(const QMimeData * data, Qt::DropAction action, int row, int column, const QModelIndex &parent) const
+{
+
+ if (!data || action != Qt::MoveAction)
return false;
- FolderNode* p = static_cast(idx.internalPointer());
+ if (!parent.isValid())
+ return false;
+ // check if the format is supported
+ QStringList types = mimeTypes();
+ if (types.isEmpty())
+ return false;
+ QString format = types.at(0);
+ if (!data->hasFormat(format))
+ return false;
+
+ QModelIndex idx = parent;
+// if (row >= rowCount(parent) || row < 0) {
+// return false;
+// } else {
+// idx= index(row,column,parent);
+// }
+ FolderNode* p= static_cast(idx.internalPointer());
PFolderNode node = mProject->pointerToNode(p);
- qDebug()<text;
if (node->unitIndex>=0)
return false;
+ QByteArray encoded = data->data(format);
+ QDataStream stream(&encoded, QIODevice::ReadOnly);
+ while (!stream.atEnd()) {
+ int r, c;
+ intptr_t v;
+ stream >> r >> c >> v;
+ FolderNode* droppedPointer= (FolderNode*)(v);
+ PFolderNode droppedNode = mProject->pointerToNode(droppedPointer);
+ PFolderNode oldParent = droppedNode->parent.lock();
+ if (oldParent == node)
+ return false;
+ }
return true;
}
-QStringList ProjectModel::mimeTypes() const
-{
- QStringList t=QAbstractItemModel::mimeTypes();
- return t;
-}
-
-QMimeData *ProjectModel::mimeData(const QModelIndexList &indexes) const
-{
- QMimeData * d= QAbstractItemModel::mimeData(indexes);
- return d;
-}
-
Qt::DropActions ProjectModel::supportedDropActions() const
{
return Qt::MoveAction;
}
+
+bool ProjectModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent)
+{
+ // check if the action is supported
+ if (!data || action != Qt::MoveAction)
+ return false;
+ // check if the format is supported
+ QStringList types = mimeTypes();
+ if (types.isEmpty())
+ return false;
+ QString format = types.at(0);
+ if (!data->hasFormat(format))
+ return false;
+
+ if (!parent.isValid())
+ return false;
+ FolderNode* p= static_cast(parent.internalPointer());
+ PFolderNode node = mProject->pointerToNode(p);
+
+ QByteArray encoded = data->data(format);
+ QDataStream stream(&encoded, QIODevice::ReadOnly);
+ QVector rows,cols;
+ QVector pointers;
+ while (!stream.atEnd()) {
+ int r, c;
+ intptr_t v;
+ stream >> r >> c >> v;
+ rows.append(r);
+ cols.append(c);
+ pointers.append(v);
+ }
+ for (int i=pointers.count()-1;i>=0;i--) {
+ int r = rows[i];
+ intptr_t v = pointers[i];
+ FolderNode* droppedPointer= (FolderNode*)(v);
+ PFolderNode droppedNode = mProject->pointerToNode(droppedPointer);
+ PFolderNode oldParent = droppedNode->parent.lock();
+ QModelIndex oldParentIndex = getParentIndex(droppedPointer);
+ beginRemoveRows(oldParentIndex,r,r);
+ if (oldParent)
+ oldParent->children.removeAt(r);
+ endRemoveRows();
+ droppedNode->parent = node;
+ node->children.append(droppedNode);
+ if (droppedNode->unitIndex>=0) {
+ PProjectUnit unit = mProject->units()[droppedNode->unitIndex];
+ unit->setFolder(mProject->getFolderPath(node));
+ }
+ QModelIndex newParentIndex = getParentIndex(droppedPointer);
+ beginInsertRows(newParentIndex,node->children.count()-1,node->children.count()-1);
+ endInsertRows();
+ mProject->saveAll();
+ return true;
+ }
+
+ return false;
+}
+
+QMimeData *ProjectModel::mimeData(const QModelIndexList &indexes) const
+{
+ if (indexes.count() <= 0)
+ return nullptr;
+ QStringList types = mimeTypes();
+ if (types.isEmpty())
+ return nullptr;
+ QMimeData *data = new QMimeData();
+ QString format = types.at(0);
+ QByteArray encoded;
+ QDataStream stream(&encoded, QIODevice::WriteOnly);
+ QModelIndexList::ConstIterator it = indexes.begin();
+ QList urls;
+ for (; it != indexes.end(); ++it) {
+ stream << (*it).row() << (*it).column() << (intptr_t)((*it).internalPointer());
+ FolderNode* p = static_cast((*it).internalPointer());
+ if (p && p->unitIndex>=0) {
+ urls.append(QUrl::fromLocalFile(mProject->units()[p->unitIndex]->fileName()));
+ }
+ }
+ if (!urls.isEmpty())
+ data->setUrls(urls);
+ data->setData(format, encoded);
+ return data;
+}
diff --git a/RedPandaIDE/project.h b/RedPandaIDE/project.h
index 75fd07c8..8bde8514 100644
--- a/RedPandaIDE/project.h
+++ b/RedPandaIDE/project.h
@@ -97,13 +97,14 @@ public:
Qt::ItemFlags flags(const QModelIndex &index) const override;
bool setData(const QModelIndex &index, const QVariant &value, int role) override;
-
+private:
+ QModelIndex getParentIndex(FolderNode * node) const;
// QAbstractItemModel interface
public:
bool canDropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) const override;
- QStringList mimeTypes() const override;
- QMimeData *mimeData(const QModelIndexList &indexes) const override;
Qt::DropActions supportedDropActions() const override;
+ bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) override;
+ QMimeData *mimeData(const QModelIndexList &indexes) const override;
};
class ProjectTemplate;