- 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
This commit is contained in:
royqh1979 2021-10-24 12:04:37 +08:00
parent 06f035926a
commit ff54e6c0e2
4 changed files with 140 additions and 41 deletions

View File

@ -6,6 +6,8 @@ Version 0.7.2
- enhancement: icons in project view - enhancement: icons in project view
- fix: sometimes option widget will show confirm dialog even not changed - fix: sometimes option widget will show confirm dialog even not changed
- enhancement: only editor area will receive file drop events - 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 Version 0.7.1
- fix: can't add bookmark at a breakpoint line - fix: can't add bookmark at a breakpoint line

View File

@ -126,7 +126,7 @@
<enum>Qt::MoveAction</enum> <enum>Qt::MoveAction</enum>
</property> </property>
<property name="selectionMode"> <property name="selectionMode">
<enum>QAbstractItemView::ExtendedSelection</enum> <enum>QAbstractItemView::SingleSelection</enum>
</property> </property>
<property name="selectionBehavior"> <property name="selectionBehavior">
<enum>QAbstractItemView::SelectRows</enum> <enum>QAbstractItemView::SelectRows</enum>

View File

@ -18,6 +18,7 @@
#include <QTextCodec> #include <QTextCodec>
#include <QMessageBox> #include <QMessageBox>
#include <QFileIconProvider> #include <QFileIconProvider>
#include <QMimeData>
#include "settings.h" #include "settings.h"
#include <QDebug> #include <QDebug>
@ -1779,18 +1780,7 @@ QModelIndex ProjectModel::parent(const QModelIndex &child) const
FolderNode * node = static_cast<FolderNode*>(child.internalPointer()); FolderNode * node = static_cast<FolderNode*>(child.internalPointer());
if (!node) if (!node)
return QModelIndex(); return QModelIndex();
PFolderNode parent = node->parent.lock(); return getParentIndex(node);
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());
} }
int ProjectModel::rowCount(const QModelIndex &parent) const int ProjectModel::rowCount(const QModelIndex &parent) const
@ -1841,7 +1831,7 @@ Qt::ItemFlags ProjectModel::flags(const QModelIndex &index) const
if (!p) if (!p)
return Qt::NoItemFlags; return Qt::NoItemFlags;
if (p==mProject->node().get()) if (p==mProject->node().get())
return Qt::ItemIsEnabled; return Qt::ItemIsEnabled | Qt::ItemIsDropEnabled;
Qt::ItemFlags flags = Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled; Qt::ItemFlags flags = Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled;
if (p->unitIndex<0) if (p->unitIndex<0)
flags.setFlag(Qt::ItemIsDropEnabled); flags.setFlag(Qt::ItemIsDropEnabled);
@ -1942,40 +1932,146 @@ bool ProjectModel::setData(const QModelIndex &index, const QVariant &value, int
return false; 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) PFolderNode parent = node->parent.lock();
return false; if (!parent) // root node
QModelIndex idx; return QModelIndex();
if (row >= rowCount(parent) || row < 0) { PFolderNode grand = parent->parent.lock();
qDebug()<<"above/below"; if (!grand) {
idx = parent; return createIndex(0,0,parent.get());
} else {
idx= index(row,column,parent);
} }
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; return false;
FolderNode* p = static_cast<FolderNode*>(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<FolderNode*>(idx.internalPointer());
PFolderNode node = mProject->pointerToNode(p); PFolderNode node = mProject->pointerToNode(p);
qDebug()<<node->text;
if (node->unitIndex>=0) if (node->unitIndex>=0)
return false; 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; 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 Qt::DropActions ProjectModel::supportedDropActions() const
{ {
return Qt::MoveAction; 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<FolderNode*>(parent.internalPointer());
PFolderNode node = mProject->pointerToNode(p);
QByteArray encoded = data->data(format);
QDataStream stream(&encoded, QIODevice::ReadOnly);
QVector<int> rows,cols;
QVector<intptr_t> 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<QUrl> urls;
for (; it != indexes.end(); ++it) {
stream << (*it).row() << (*it).column() << (intptr_t)((*it).internalPointer());
FolderNode* p = static_cast<FolderNode*>((*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;
}

View File

@ -97,13 +97,14 @@ public:
Qt::ItemFlags flags(const QModelIndex &index) const override; Qt::ItemFlags flags(const QModelIndex &index) const override;
bool setData(const QModelIndex &index, const QVariant &value, int role) override; bool setData(const QModelIndex &index, const QVariant &value, int role) override;
private:
QModelIndex getParentIndex(FolderNode * node) const;
// QAbstractItemModel interface // QAbstractItemModel interface
public: public:
bool canDropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) const override; 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; 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; class ProjectTemplate;