Added drag/drop support to directory tree view
This commit is contained in:
parent
ca40c26154
commit
18482cbae6
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -94,7 +94,7 @@ bool CEditorApplication::OpenProject(const QString& rkProjPath)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
UICommon::ErrorMsg(mpWorldEditor, "Failed to open project! Is it already open in another Prime World Editor instance?");
|
UICommon::ErrorMsg(mpWorldEditor, "Failed to open project!");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -195,7 +195,8 @@ HEADERS += \
|
||||||
Undo/CRenameResourceCommand.h \
|
Undo/CRenameResourceCommand.h \
|
||||||
Undo/CRenameDirectoryCommand.h \
|
Undo/CRenameDirectoryCommand.h \
|
||||||
CFileNameValidator.h \
|
CFileNameValidator.h \
|
||||||
Undo/ICreateDeleteDirectoryCommand.h
|
Undo/ICreateDeleteDirectoryCommand.h \
|
||||||
|
ResourceBrowser/CVirtualDirectoryTreeView.h
|
||||||
|
|
||||||
# Source Files
|
# Source Files
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
|
@ -268,7 +269,8 @@ SOURCES += \
|
||||||
ResourceBrowser/CResourceTableContextMenu.cpp \
|
ResourceBrowser/CResourceTableContextMenu.cpp \
|
||||||
ResourceBrowser/CResourceTableModel.cpp \
|
ResourceBrowser/CResourceTableModel.cpp \
|
||||||
ResourceBrowser/CResourceTableView.cpp \
|
ResourceBrowser/CResourceTableView.cpp \
|
||||||
ResourceBrowser/CVirtualDirectoryModel.cpp
|
ResourceBrowser/CVirtualDirectoryModel.cpp \
|
||||||
|
ResourceBrowser/CVirtualDirectoryTreeView.cpp
|
||||||
|
|
||||||
# UI Files
|
# UI Files
|
||||||
FORMS += \
|
FORMS += \
|
||||||
|
|
|
@ -327,19 +327,35 @@ bool CResourceBrowser::MoveResources(const QList<CResourceEntry*>& rkResources,
|
||||||
{
|
{
|
||||||
// Check for any conflicts
|
// Check for any conflicts
|
||||||
QList<CResourceEntry*> ConflictingResources;
|
QList<CResourceEntry*> ConflictingResources;
|
||||||
|
QList<CResourceEntry*> ValidResources;
|
||||||
|
|
||||||
foreach (CResourceEntry *pEntry, rkResources)
|
foreach (CResourceEntry *pEntry, rkResources)
|
||||||
{
|
{
|
||||||
if (pNewDir->FindChildResource(pEntry->Name(), pEntry->ResourceType()) != nullptr)
|
CResourceEntry *pConflict = pNewDir->FindChildResource(pEntry->Name(), pEntry->ResourceType());
|
||||||
ConflictingResources << pEntry;
|
|
||||||
|
if (pConflict != pEntry)
|
||||||
|
{
|
||||||
|
if (pConflict != nullptr)
|
||||||
|
ConflictingResources << pEntry;
|
||||||
|
else
|
||||||
|
ValidResources << pEntry;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<CVirtualDirectory*> ConflictingDirs;
|
QList<CVirtualDirectory*> ConflictingDirs;
|
||||||
|
QList<CVirtualDirectory*> ValidDirs;
|
||||||
|
|
||||||
foreach (CVirtualDirectory *pDir, rkDirectories)
|
foreach (CVirtualDirectory *pDir, rkDirectories)
|
||||||
{
|
{
|
||||||
if (pNewDir->FindChildDirectory(pDir->Name(), false) != nullptr)
|
CVirtualDirectory *pConflict = pNewDir->FindChildDirectory(pDir->Name(), false);
|
||||||
ConflictingDirs << pDir;
|
|
||||||
|
if (pConflict != pDir)
|
||||||
|
{
|
||||||
|
if (pConflict != nullptr)
|
||||||
|
ConflictingDirs << pDir;
|
||||||
|
else
|
||||||
|
ValidDirs << pDir;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If there were conflicts, notify the user of them
|
// If there were conflicts, notify the user of them
|
||||||
|
@ -362,15 +378,19 @@ bool CResourceBrowser::MoveResources(const QList<CResourceEntry*>& rkResources,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create undo actions to actually perform the moves
|
// Create undo actions to actually perform the moves
|
||||||
mUndoStack.beginMacro("Move Resources");
|
if (!ValidResources.isEmpty() || !ValidDirs.isEmpty())
|
||||||
|
{
|
||||||
|
mUndoStack.beginMacro("Move Resources");
|
||||||
|
|
||||||
foreach (CVirtualDirectory *pDir, rkDirectories)
|
foreach (CVirtualDirectory *pDir, ValidDirs)
|
||||||
mUndoStack.push( new CMoveDirectoryCommand(mpStore, pDir, pNewDir) );
|
mUndoStack.push( new CMoveDirectoryCommand(mpStore, pDir, pNewDir) );
|
||||||
|
|
||||||
foreach (CResourceEntry *pEntry, rkResources)
|
foreach (CResourceEntry *pEntry, ValidResources)
|
||||||
mUndoStack.push( new CMoveResourceCommand(pEntry, pNewDir) );
|
mUndoStack.push( new CMoveResourceCommand(pEntry, pNewDir) );
|
||||||
|
|
||||||
|
mUndoStack.endMacro();
|
||||||
|
}
|
||||||
|
|
||||||
mUndoStack.endMacro();
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -255,7 +255,7 @@
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QTreeView" name="DirectoryTreeView">
|
<widget class="CVirtualDirectoryTreeView" name="DirectoryTreeView">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
|
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
|
||||||
<horstretch>0</horstretch>
|
<horstretch>0</horstretch>
|
||||||
|
@ -268,7 +268,19 @@
|
||||||
</font>
|
</font>
|
||||||
</property>
|
</property>
|
||||||
<property name="editTriggers">
|
<property name="editTriggers">
|
||||||
<set>QAbstractItemView::NoEditTriggers</set>
|
<set>QAbstractItemView::EditKeyPressed</set>
|
||||||
|
</property>
|
||||||
|
<property name="dragEnabled">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="dragDropOverwriteMode">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="dragDropMode">
|
||||||
|
<enum>QAbstractItemView::DragDrop</enum>
|
||||||
|
</property>
|
||||||
|
<property name="defaultDropAction">
|
||||||
|
<enum>Qt::MoveAction</enum>
|
||||||
</property>
|
</property>
|
||||||
<property name="alternatingRowColors">
|
<property name="alternatingRowColors">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
|
@ -285,6 +297,9 @@
|
||||||
<property name="verticalScrollMode">
|
<property name="verticalScrollMode">
|
||||||
<enum>QAbstractItemView::ScrollPerPixel</enum>
|
<enum>QAbstractItemView::ScrollPerPixel</enum>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="autoExpandDelay">
|
||||||
|
<number>-1</number>
|
||||||
|
</property>
|
||||||
<property name="indentation">
|
<property name="indentation">
|
||||||
<number>12</number>
|
<number>12</number>
|
||||||
</property>
|
</property>
|
||||||
|
@ -311,7 +326,7 @@
|
||||||
<enum>Qt::CustomContextMenu</enum>
|
<enum>Qt::CustomContextMenu</enum>
|
||||||
</property>
|
</property>
|
||||||
<property name="editTriggers">
|
<property name="editTriggers">
|
||||||
<set>QAbstractItemView::NoEditTriggers</set>
|
<set>QAbstractItemView::EditKeyPressed</set>
|
||||||
</property>
|
</property>
|
||||||
<property name="dragEnabled">
|
<property name="dragEnabled">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
|
@ -362,6 +377,11 @@
|
||||||
<extends>QTableView</extends>
|
<extends>QTableView</extends>
|
||||||
<header>Editor/ResourceBrowser/CResourceTableView.h</header>
|
<header>Editor/ResourceBrowser/CResourceTableView.h</header>
|
||||||
</customwidget>
|
</customwidget>
|
||||||
|
<customwidget>
|
||||||
|
<class>CVirtualDirectoryTreeView</class>
|
||||||
|
<extends>QTreeView</extends>
|
||||||
|
<header>Editor/ResourceBrowser/CVirtualDirectoryTreeView.h</header>
|
||||||
|
</customwidget>
|
||||||
</customwidgets>
|
</customwidgets>
|
||||||
<resources>
|
<resources>
|
||||||
<include location="../Icons.qrc"/>
|
<include location="../Icons.qrc"/>
|
||||||
|
|
|
@ -24,6 +24,12 @@ public:
|
||||||
mEntries << pEntry;
|
mEntries << pEntry;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CResourceMimeData(CVirtualDirectory *pDir)
|
||||||
|
: QMimeData()
|
||||||
|
{
|
||||||
|
mDirectories << pDir;
|
||||||
|
}
|
||||||
|
|
||||||
const QList<CResourceEntry*>& Resources() const { return mEntries; }
|
const QList<CResourceEntry*>& Resources() const { return mEntries; }
|
||||||
const QList<CVirtualDirectory*>& Directories() const { return mDirectories; }
|
const QList<CVirtualDirectory*>& Directories() const { return mDirectories; }
|
||||||
};
|
};
|
||||||
|
|
|
@ -62,41 +62,47 @@ QVariant CResourceTableModel::data(const QModelIndex& rkIndex, int Role) const
|
||||||
|
|
||||||
Qt::ItemFlags CResourceTableModel::flags(const QModelIndex& rkIndex) const
|
Qt::ItemFlags CResourceTableModel::flags(const QModelIndex& rkIndex) const
|
||||||
{
|
{
|
||||||
Qt::ItemFlags Out = Qt::ItemIsSelectable | Qt::ItemIsDragEnabled | Qt::ItemIsEnabled | Qt::ItemIsEditable;
|
Qt::ItemFlags Out = Qt::ItemIsSelectable |Qt::ItemIsEnabled;
|
||||||
|
CVirtualDirectory *pDir = IndexDirectory(rkIndex);
|
||||||
|
|
||||||
if (IsIndexDirectory(rkIndex))
|
if (pDir)
|
||||||
Out |= Qt::ItemIsDropEnabled;
|
Out |= Qt::ItemIsDropEnabled;
|
||||||
|
|
||||||
|
if (!pDir || mpCurrentDir->Parent() != pDir)
|
||||||
|
Out |= Qt::ItemIsEditable | Qt::ItemIsDragEnabled;
|
||||||
|
|
||||||
return Out;
|
return Out;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CResourceTableModel::canDropMimeData(const QMimeData *pkData, Qt::DropAction, int Row, int Column, const QModelIndex& rkParent) const
|
bool CResourceTableModel::canDropMimeData(const QMimeData *pkData, Qt::DropAction, int Row, int Column, const QModelIndex& rkParent) const
|
||||||
{
|
{
|
||||||
|
// Don't allow dropping between items.
|
||||||
|
if (Row != -1 || Column != -1)
|
||||||
|
return false;
|
||||||
|
|
||||||
const CResourceMimeData *pkMimeData = qobject_cast<const CResourceMimeData*>(pkData);
|
const CResourceMimeData *pkMimeData = qobject_cast<const CResourceMimeData*>(pkData);
|
||||||
|
|
||||||
if (pkMimeData)
|
if (pkMimeData)
|
||||||
{
|
{
|
||||||
|
// Don't allow dropping onto blank space in asset list mode
|
||||||
|
if (!rkParent.isValid() && mIsAssetListMode)
|
||||||
|
return false;
|
||||||
|
|
||||||
// Make sure we're dropping onto a directory
|
// Make sure we're dropping onto a directory
|
||||||
QModelIndex Index = (rkParent.isValid() ? rkParent : index(Row, Column, rkParent));
|
CVirtualDirectory *pDir = (rkParent.isValid() ? IndexDirectory(rkParent) : mpCurrentDir);
|
||||||
|
|
||||||
if (Index.isValid())
|
if (pDir)
|
||||||
{
|
{
|
||||||
CVirtualDirectory *pDir = IndexDirectory(Index);
|
// Make sure this directory isn't part of the mime data, or a subdirectory of a directory in the mime data
|
||||||
|
foreach (CVirtualDirectory *pMimeDir, pkMimeData->Directories())
|
||||||
if (pDir)
|
|
||||||
{
|
{
|
||||||
// Make sure this directory isn't part of the mime data, or a subdirectory of a directory in the mime data
|
if (pDir == pMimeDir || pDir->IsDescendantOf(pMimeDir))
|
||||||
foreach (CVirtualDirectory *pMimeDir, pkMimeData->Directories())
|
return false;
|
||||||
{
|
|
||||||
if (pDir == pMimeDir || pDir->IsDescendantOf(pMimeDir))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Valid directory
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Valid directory
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
else return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@ -108,12 +114,10 @@ bool CResourceTableModel::dropMimeData(const QMimeData *pkData, Qt::DropAction A
|
||||||
|
|
||||||
if (canDropMimeData(pkData, Action, Row, Column, rkParent))
|
if (canDropMimeData(pkData, Action, Row, Column, rkParent))
|
||||||
{
|
{
|
||||||
QModelIndex Index = (rkParent.isValid() ? rkParent : index(Row, Column, rkParent));
|
CVirtualDirectory *pDir = (rkParent.isValid() ? IndexDirectory(rkParent) : mpCurrentDir);
|
||||||
CVirtualDirectory *pDir = IndexDirectory(Index);
|
|
||||||
ASSERT(pDir);
|
ASSERT(pDir);
|
||||||
|
|
||||||
gpEdApp->ResourceBrowser()->MoveResources( pkMimeData->Resources(), pkMimeData->Directories(), pDir );
|
return gpEdApp->ResourceBrowser()->MoveResources( pkMimeData->Resources(), pkMimeData->Directories(), pDir );
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
else return false;
|
else return false;
|
||||||
}
|
}
|
||||||
|
@ -298,7 +302,7 @@ void CResourceTableModel::CheckAddDirectory(CVirtualDirectory *pDir)
|
||||||
|
|
||||||
void CResourceTableModel::CheckRemoveDirectory(CVirtualDirectory *pDir)
|
void CResourceTableModel::CheckRemoveDirectory(CVirtualDirectory *pDir)
|
||||||
{
|
{
|
||||||
if (pDir->Parent() == mpCurrentDir)
|
if (pDir->Parent() != mpCurrentDir)
|
||||||
{
|
{
|
||||||
QModelIndex Index = GetIndexForDirectory(pDir);
|
QModelIndex Index = GetIndexForDirectory(pDir);
|
||||||
|
|
||||||
|
|
|
@ -7,17 +7,13 @@
|
||||||
CResourceTableView::CResourceTableView(QWidget *pParent /*= 0*/)
|
CResourceTableView::CResourceTableView(QWidget *pParent /*= 0*/)
|
||||||
: QTableView(pParent)
|
: QTableView(pParent)
|
||||||
{
|
{
|
||||||
// Create "rename" key shortcut
|
// todo: removed delete shortcut because it conflicts with the World Editor delete shortcut
|
||||||
// todo - there's no QKeySequence::Rename. Is there another standard "rename" shortcut on other platforms?
|
#if 0
|
||||||
mpRenameAction = new QAction(this);
|
|
||||||
mpRenameAction->setShortcut( QKeySequence(Qt::Key_F2) );
|
|
||||||
connect(mpRenameAction, SIGNAL(triggered(bool)), this, SLOT(RenameSelected()));
|
|
||||||
addAction(mpRenameAction);
|
|
||||||
|
|
||||||
mpDeleteAction = new QAction(this);
|
mpDeleteAction = new QAction(this);
|
||||||
mpDeleteAction->setShortcut(QKeySequence::Delete);
|
mpDeleteAction->setShortcut(QKeySequence::Delete);
|
||||||
connect(mpDeleteAction, SIGNAL(triggered(bool)), this, SLOT(DeleteSelected()));
|
connect(mpDeleteAction, SIGNAL(triggered(bool)), this, SLOT(DeleteSelected()));
|
||||||
addAction(mpDeleteAction);
|
addAction(mpDeleteAction);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void CResourceTableView::setModel(QAbstractItemModel *pModel)
|
void CResourceTableView::setModel(QAbstractItemModel *pModel)
|
||||||
|
@ -40,27 +36,7 @@ void CResourceTableView::dragEnterEvent(QDragEnterEvent *pEvent)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CResourceTableView::focusInEvent(QFocusEvent*)
|
|
||||||
{
|
|
||||||
mpRenameAction->setEnabled(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CResourceTableView::focusOutEvent(QFocusEvent*)
|
|
||||||
{
|
|
||||||
mpRenameAction->setEnabled(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ************ SLOTS ************
|
// ************ SLOTS ************
|
||||||
void CResourceTableView::RenameSelected()
|
|
||||||
{
|
|
||||||
QModelIndexList List = selectionModel()->selectedIndexes();
|
|
||||||
|
|
||||||
if (List.size() == 1)
|
|
||||||
{
|
|
||||||
edit(List.front());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CResourceTableView::DeleteSelected()
|
void CResourceTableView::DeleteSelected()
|
||||||
{
|
{
|
||||||
QModelIndexList List = selectionModel()->selectedIndexes();
|
QModelIndexList List = selectionModel()->selectedIndexes();
|
||||||
|
|
|
@ -11,19 +11,14 @@ class CResourceTableView : public QTableView
|
||||||
|
|
||||||
CResourceTableModel *mpModel;
|
CResourceTableModel *mpModel;
|
||||||
CResourceProxyModel *mpProxy;
|
CResourceProxyModel *mpProxy;
|
||||||
|
|
||||||
QAction *mpRenameAction;
|
|
||||||
QAction *mpDeleteAction;
|
QAction *mpDeleteAction;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit CResourceTableView(QWidget *pParent = 0);
|
explicit CResourceTableView(QWidget *pParent = 0);
|
||||||
void setModel(QAbstractItemModel *pModel);
|
void setModel(QAbstractItemModel *pModel);
|
||||||
void dragEnterEvent(QDragEnterEvent *pEvent);
|
void dragEnterEvent(QDragEnterEvent *pEvent);
|
||||||
void focusInEvent(QFocusEvent*);
|
|
||||||
void focusOutEvent(QFocusEvent*);
|
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void RenameSelected();
|
|
||||||
void DeleteSelected();
|
void DeleteSelected();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,13 @@
|
||||||
#include "CVirtualDirectoryModel.h"
|
#include "CVirtualDirectoryModel.h"
|
||||||
#include "CResourceBrowser.h"
|
#include "CResourceBrowser.h"
|
||||||
|
#include "CResourceMimeData.h"
|
||||||
|
|
||||||
CVirtualDirectoryModel::CVirtualDirectoryModel(CResourceBrowser *pBrowser, QObject *pParent /*= 0*/)
|
CVirtualDirectoryModel::CVirtualDirectoryModel(CResourceBrowser *pBrowser, QObject *pParent /*= 0*/)
|
||||||
: QAbstractItemModel(pParent)
|
: QAbstractItemModel(pParent)
|
||||||
, mpRoot(nullptr)
|
, mpRoot(nullptr)
|
||||||
, mInsertingRows(false)
|
, mInsertingRows(false)
|
||||||
, mRemovingRows(false)
|
, mRemovingRows(false)
|
||||||
|
, mMovingRows(false)
|
||||||
, mChangingLayout(false)
|
, mChangingLayout(false)
|
||||||
{
|
{
|
||||||
connect(pBrowser, SIGNAL(DirectoryAboutToBeMoved(CVirtualDirectory*,QString)), this, SLOT(OnDirectoryAboutToBeMoved(CVirtualDirectory*,QString)));
|
connect(pBrowser, SIGNAL(DirectoryAboutToBeMoved(CVirtualDirectory*,QString)), this, SLOT(OnDirectoryAboutToBeMoved(CVirtualDirectory*,QString)));
|
||||||
|
@ -95,6 +97,102 @@ QVariant CVirtualDirectoryModel::data(const QModelIndex& rkIndex, int Role) cons
|
||||||
return QVariant::Invalid;
|
return QVariant::Invalid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CVirtualDirectoryModel::setData(const QModelIndex& rkIndex, const QVariant& rkValue, int Role)
|
||||||
|
{
|
||||||
|
if (Role == Qt::EditRole)
|
||||||
|
{
|
||||||
|
QString NewName = rkValue.toString();
|
||||||
|
CVirtualDirectory *pDir = IndexDirectory(rkIndex);
|
||||||
|
|
||||||
|
if (pDir)
|
||||||
|
{
|
||||||
|
gpEdApp->ResourceBrowser()->RenameDirectory(pDir, TO_TSTRING(NewName));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Qt::ItemFlags CVirtualDirectoryModel::flags(const QModelIndex& rkIndex) const
|
||||||
|
{
|
||||||
|
Qt::ItemFlags Out = Qt::ItemIsSelectable | Qt::ItemIsDropEnabled | Qt::ItemIsEnabled;
|
||||||
|
|
||||||
|
if (rkIndex.isValid() && rkIndex.parent().isValid())
|
||||||
|
Out |= Qt::ItemIsEditable | Qt::ItemIsDragEnabled;
|
||||||
|
|
||||||
|
return Out;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CVirtualDirectoryModel::canDropMimeData(const QMimeData *pkData, Qt::DropAction Action, int Row, int Column, const QModelIndex& rkParent) const
|
||||||
|
{
|
||||||
|
// Don't allow dropping between items
|
||||||
|
if (Row != -1 || Column != -1)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (Action == Qt::MoveAction)
|
||||||
|
{
|
||||||
|
CVirtualDirectory *pDir = IndexDirectory(rkParent);
|
||||||
|
|
||||||
|
if (pDir)
|
||||||
|
{
|
||||||
|
const CResourceMimeData *pkMimeData = qobject_cast<const CResourceMimeData*>(pkData);
|
||||||
|
|
||||||
|
if (pkMimeData)
|
||||||
|
{
|
||||||
|
// Don't allow moving a directory into one of its children
|
||||||
|
foreach (CVirtualDirectory *pMoveDir, pkMimeData->Directories())
|
||||||
|
{
|
||||||
|
if (pDir->IsDescendantOf(pMoveDir))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CVirtualDirectoryModel::dropMimeData(const QMimeData *pkData, Qt::DropAction Action, int Row, int Column, const QModelIndex& rkParent)
|
||||||
|
{
|
||||||
|
// Perform move!
|
||||||
|
const CResourceMimeData *pkMimeData = qobject_cast<const CResourceMimeData*>(pkData);
|
||||||
|
|
||||||
|
if (canDropMimeData(pkData, Action, Row, Column, rkParent))
|
||||||
|
{
|
||||||
|
CVirtualDirectory *pDir = IndexDirectory(rkParent);
|
||||||
|
ASSERT(pDir);
|
||||||
|
|
||||||
|
return gpEdApp->ResourceBrowser()->MoveResources(pkMimeData->Resources(), pkMimeData->Directories(), pDir);
|
||||||
|
}
|
||||||
|
else return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
QMimeData* CVirtualDirectoryModel::mimeData(const QModelIndexList& rkIndexes) const
|
||||||
|
{
|
||||||
|
if (rkIndexes.size() == 1)
|
||||||
|
{
|
||||||
|
QModelIndex Index = rkIndexes.front();
|
||||||
|
CVirtualDirectory *pDir = IndexDirectory(Index);
|
||||||
|
CResourceMimeData *pMimeData = new CResourceMimeData(pDir);
|
||||||
|
return pMimeData;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
Qt::DropActions CVirtualDirectoryModel::supportedDragActions() const
|
||||||
|
{
|
||||||
|
return Qt::CopyAction | Qt::MoveAction;
|
||||||
|
}
|
||||||
|
|
||||||
|
Qt::DropActions CVirtualDirectoryModel::supportedDropActions() const
|
||||||
|
{
|
||||||
|
return Qt::MoveAction;
|
||||||
|
}
|
||||||
|
|
||||||
QModelIndex CVirtualDirectoryModel::GetIndexForDirectory(CVirtualDirectory *pDir)
|
QModelIndex CVirtualDirectoryModel::GetIndexForDirectory(CVirtualDirectory *pDir)
|
||||||
{
|
{
|
||||||
if (!pDir)
|
if (!pDir)
|
||||||
|
@ -184,10 +282,28 @@ bool CVirtualDirectoryModel::GetProposedIndex(QString Path, QModelIndex& rOutPar
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CVirtualDirectoryModel::OnDirectoryAboutToBeMoved(CVirtualDirectory *, QString )
|
void CVirtualDirectoryModel::OnDirectoryAboutToBeMoved(CVirtualDirectory *pDir, QString NewPath)
|
||||||
{
|
{
|
||||||
emit layoutAboutToBeChanged();
|
QModelIndex Parent;
|
||||||
mChangingLayout = true;
|
int Row;
|
||||||
|
|
||||||
|
if (GetProposedIndex(NewPath, Parent, Row))
|
||||||
|
{
|
||||||
|
QModelIndex OldIndex = GetIndexForDirectory(pDir);
|
||||||
|
QModelIndex OldParent = OldIndex.parent();
|
||||||
|
int OldRow = OldIndex.row();
|
||||||
|
|
||||||
|
if (OldParent == Parent && (Row == OldRow || Row == OldRow + 1))
|
||||||
|
{
|
||||||
|
emit layoutAboutToBeChanged();
|
||||||
|
mChangingLayout = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
beginMoveRows(OldParent, OldRow, OldRow, Parent, Row);
|
||||||
|
mMovingRows = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CVirtualDirectoryModel::OnDirectoryAboutToBeCreated(QString DirPath)
|
void CVirtualDirectoryModel::OnDirectoryAboutToBeCreated(QString DirPath)
|
||||||
|
@ -225,6 +341,11 @@ void CVirtualDirectoryModel::FinishModelChanges()
|
||||||
endRemoveRows();
|
endRemoveRows();
|
||||||
mRemovingRows = false;
|
mRemovingRows = false;
|
||||||
}
|
}
|
||||||
|
if (mMovingRows)
|
||||||
|
{
|
||||||
|
endMoveRows();
|
||||||
|
mMovingRows = false;
|
||||||
|
}
|
||||||
if (mChangingLayout)
|
if (mChangingLayout)
|
||||||
{
|
{
|
||||||
emit layoutChanged();
|
emit layoutChanged();
|
||||||
|
|
|
@ -12,6 +12,7 @@ class CVirtualDirectoryModel : public QAbstractItemModel
|
||||||
CVirtualDirectory *mpRoot;
|
CVirtualDirectory *mpRoot;
|
||||||
bool mInsertingRows;
|
bool mInsertingRows;
|
||||||
bool mRemovingRows;
|
bool mRemovingRows;
|
||||||
|
bool mMovingRows;
|
||||||
bool mChangingLayout;
|
bool mChangingLayout;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -22,6 +23,14 @@ public:
|
||||||
int rowCount(const QModelIndex& rkParent) const;
|
int rowCount(const QModelIndex& rkParent) const;
|
||||||
int columnCount(const QModelIndex& /*rkParent*/) const;
|
int columnCount(const QModelIndex& /*rkParent*/) const;
|
||||||
QVariant data(const QModelIndex& rkIndex, int Role) const;
|
QVariant data(const QModelIndex& rkIndex, int Role) const;
|
||||||
|
bool setData(const QModelIndex& rkIndex, const QVariant& rkValue, int Role);
|
||||||
|
Qt::ItemFlags flags(const QModelIndex& rkIndex) const;
|
||||||
|
|
||||||
|
bool canDropMimeData(const QMimeData *pkData, Qt::DropAction Action, int Row, int Column, const QModelIndex& rkParent) const;
|
||||||
|
bool dropMimeData(const QMimeData *pkData, Qt::DropAction Action, int Row, int Column, const QModelIndex& rkParent);
|
||||||
|
QMimeData* mimeData(const QModelIndexList& rkIndexes) const;
|
||||||
|
Qt::DropActions supportedDragActions() const;
|
||||||
|
Qt::DropActions supportedDropActions() const;
|
||||||
|
|
||||||
QModelIndex GetIndexForDirectory(CVirtualDirectory *pDir);
|
QModelIndex GetIndexForDirectory(CVirtualDirectory *pDir);
|
||||||
CVirtualDirectory* IndexDirectory(const QModelIndex& rkIndex) const;
|
CVirtualDirectory* IndexDirectory(const QModelIndex& rkIndex) const;
|
||||||
|
|
|
@ -0,0 +1,78 @@
|
||||||
|
#include "CVirtualDirectoryTreeView.h"
|
||||||
|
#include "CResourceBrowser.h"
|
||||||
|
#include "CVirtualDirectoryModel.h"
|
||||||
|
#include <QDragEnterEvent>
|
||||||
|
|
||||||
|
CVirtualDirectoryTreeView::CVirtualDirectoryTreeView(QWidget *pParent)
|
||||||
|
: QTreeView(pParent)
|
||||||
|
, mTransferSelectionPostMove(false)
|
||||||
|
{
|
||||||
|
// slightly hacky cuz there's not really a good way to pass in CResourceBrowser as a parameter
|
||||||
|
// due to the fact that we set this class in the .ui file
|
||||||
|
CResourceBrowser *pBrowser = nullptr;
|
||||||
|
QWidget *pWidget = pParent;
|
||||||
|
|
||||||
|
while (pWidget && !pBrowser)
|
||||||
|
{
|
||||||
|
pBrowser = qobject_cast<CResourceBrowser*>(pWidget);
|
||||||
|
pWidget = pWidget->parentWidget();
|
||||||
|
}
|
||||||
|
ASSERT(pBrowser);
|
||||||
|
|
||||||
|
connect(pBrowser, SIGNAL(DirectoryAboutToBeMoved(CVirtualDirectory*,QString)), this, SLOT(OnDirectoryAboutToBeMoved(CVirtualDirectory*)));
|
||||||
|
connect(pBrowser, SIGNAL(DirectoryMoved(CVirtualDirectory*,CVirtualDirectory*,TString)), this, SLOT(OnDirectoryMoved(CVirtualDirectory*)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void CVirtualDirectoryTreeView::dragEnterEvent(QDragEnterEvent *pEvent)
|
||||||
|
{
|
||||||
|
// need to reimplement this to fix a bug in QAbstractItemView
|
||||||
|
if (dragDropMode() == QAbstractItemView::InternalMove &&
|
||||||
|
(pEvent->source() != this || ((pEvent->possibleActions() & Qt::MoveAction) == 0)) )
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (pEvent->possibleActions() & model()->supportedDropActions())
|
||||||
|
{
|
||||||
|
pEvent->accept();
|
||||||
|
setState(QAbstractItemView::DraggingState);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CVirtualDirectoryTreeView::setModel(QAbstractItemModel *pModel)
|
||||||
|
{
|
||||||
|
CVirtualDirectoryModel *pDirModel = qobject_cast<CVirtualDirectoryModel*>(pModel);
|
||||||
|
|
||||||
|
if (pDirModel)
|
||||||
|
{
|
||||||
|
mpModel = pDirModel;
|
||||||
|
QTreeView::setModel(pModel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CVirtualDirectoryTreeView::OnDirectoryAboutToBeMoved(CVirtualDirectory *pDir)
|
||||||
|
{
|
||||||
|
if (mpModel)
|
||||||
|
{
|
||||||
|
QModelIndex Index = mpModel->GetIndexForDirectory(pDir);
|
||||||
|
|
||||||
|
if (selectionModel()->currentIndex() == Index)
|
||||||
|
mTransferSelectionPostMove = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CVirtualDirectoryTreeView::OnDirectoryMoved(CVirtualDirectory *pDir)
|
||||||
|
{
|
||||||
|
if (mTransferSelectionPostMove)
|
||||||
|
{
|
||||||
|
// Make sure the model has updated first
|
||||||
|
mpModel->FinishModelChanges();
|
||||||
|
|
||||||
|
QModelIndex Index = mpModel->GetIndexForDirectory(pDir);
|
||||||
|
|
||||||
|
blockSignals(true);
|
||||||
|
expand(Index.parent());
|
||||||
|
selectionModel()->setCurrentIndex(Index, QItemSelectionModel::ClearAndSelect);
|
||||||
|
blockSignals(false);
|
||||||
|
|
||||||
|
mTransferSelectionPostMove = false;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
#ifndef CVIRTUALDIRECTORYTREEVIEW_H
|
||||||
|
#define CVIRTUALDIRECTORYTREEVIEW_H
|
||||||
|
|
||||||
|
#include <QTreeView>
|
||||||
|
#include "CVirtualDirectoryModel.h"
|
||||||
|
#include <Core/GameProject/CVirtualDirectory.h>
|
||||||
|
|
||||||
|
class CVirtualDirectoryTreeView : public QTreeView
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
CVirtualDirectoryModel *mpModel;
|
||||||
|
bool mTransferSelectionPostMove;
|
||||||
|
|
||||||
|
public:
|
||||||
|
CVirtualDirectoryTreeView(QWidget *pParent = 0);
|
||||||
|
void dragEnterEvent(QDragEnterEvent *pEvent);
|
||||||
|
void setModel(QAbstractItemModel *pModel);
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void OnDirectoryAboutToBeMoved(CVirtualDirectory *pDir);
|
||||||
|
void OnDirectoryMoved(CVirtualDirectory *pDir);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // CVIRTUALDIRECTORYTREEVIEW_H
|
|
@ -34,7 +34,7 @@ protected:
|
||||||
CVirtualDirectory *pParent = mpStore->GetVirtualDirectory(rkPath, false);
|
CVirtualDirectory *pParent = mpStore->GetVirtualDirectory(rkPath, false);
|
||||||
ASSERT(pDir && pParent);
|
ASSERT(pDir && pParent);
|
||||||
|
|
||||||
gpEdApp->ResourceBrowser()->DirectoryAboutToBeMoved(pDir, TO_QSTRING(rkPath));
|
gpEdApp->ResourceBrowser()->DirectoryAboutToBeMoved(pDir, TO_QSTRING(rkPath + pDir->Name()));
|
||||||
|
|
||||||
TString OldName = pDir->Name();
|
TString OldName = pDir->Name();
|
||||||
CVirtualDirectory *pOldParent = pDir->Parent();
|
CVirtualDirectory *pOldParent = pDir->Parent();
|
||||||
|
|
Loading…
Reference in New Issue