forked from qt-creator/qt-creator
QmlDesigner: Track folders expanded/collapsed state in AssetsLibrary
Fixes: QDS-13791 Change-Id: I6d30e6d1d79da99466f0fa7b762267701bc2d2e2 Reviewed-by: Miikka Heikkinen <miikka.heikkinen@qt.io>
This commit is contained in:
@@ -48,6 +48,19 @@ TreeViewDelegate {
|
||||
root.depth -= root.assetsView.rootPathDepth
|
||||
root.initialDepth = root.depth
|
||||
}
|
||||
|
||||
// expand/collapse folder based on its stored expanded state
|
||||
if (root.__isDirectory) {
|
||||
// if the folder expand state is not stored yet, stores it as true (expanded)
|
||||
root.assetsModel.initializeExpandState(root.__itemPath)
|
||||
|
||||
let expandState = assetsModel.folderExpandState(root.__itemPath)
|
||||
|
||||
if (expandState)
|
||||
root.assetsView.expand(root.__currentRow)
|
||||
else
|
||||
root.assetsView.collapse(root.__currentRow)
|
||||
}
|
||||
}
|
||||
|
||||
// workaround for a bug -- might be fixed by https://codereview.qt-project.org/c/qt/qtdeclarative/+/442721
|
||||
@@ -295,6 +308,8 @@ TreeViewDelegate {
|
||||
} else {
|
||||
root.assetsView.expand(root.__currentRow)
|
||||
}
|
||||
|
||||
assetsModel.saveExpandState(root.__itemPath, root.expanded)
|
||||
}
|
||||
|
||||
function reloadImage() {
|
||||
|
@@ -93,7 +93,6 @@ TreeView {
|
||||
function onDirectoryCreated(path)
|
||||
{
|
||||
root.__createdDirectories.push(path)
|
||||
|
||||
updateRowsTimer.restart()
|
||||
}
|
||||
|
||||
@@ -118,15 +117,7 @@ TreeView {
|
||||
// updating rows for safety: the rows might have been created before the
|
||||
// directory (esp. the root path) has been loaded, so we must make sure all rows are
|
||||
// expanded -- otherwise, the tree may not become visible.
|
||||
|
||||
updateRowsTimer.restart()
|
||||
|
||||
let idx = assetsModel.indexForPath(path)
|
||||
let row = root.rowAtIndex(idx)
|
||||
let column = root.columnAtIndex(idx)
|
||||
|
||||
if (row >= root.rootPathRow && !root.isExpanded(row))
|
||||
root.expand(row)
|
||||
}
|
||||
|
||||
function onRootPathChanged()
|
||||
@@ -180,9 +171,9 @@ TreeView {
|
||||
let index = assetsModel.indexForPath(dirPath)
|
||||
let row = root.rowAtIndex(index)
|
||||
|
||||
if (row > 0)
|
||||
if (row > 0) {
|
||||
root.expand(row)
|
||||
else if (row === -1 && assetsModel.indexIsValid(index)) {
|
||||
} else if (row === -1 && assetsModel.indexIsValid(index)) {
|
||||
// It is possible that this directory, dirPath, was created inside of a parent
|
||||
// directory that was not yet expanded in the TreeView. This can happen with the
|
||||
// bridge plugin. In such a situation, we don't have a "row" for it yet, so we have
|
||||
@@ -194,6 +185,8 @@ TreeView {
|
||||
root.expand(row)
|
||||
})
|
||||
}
|
||||
|
||||
assetsModel.saveExpandState(dirPath, root.isExpanded(row))
|
||||
}
|
||||
|
||||
// we have no way to know beyond doubt here if updateRows() was called due
|
||||
@@ -215,10 +208,10 @@ TreeView {
|
||||
function __doExpandAll()
|
||||
{
|
||||
let expandedAny = false
|
||||
for (let nRow = 0; nRow < root.rows; ++nRow) {
|
||||
let index = root.__modelIndex(nRow)
|
||||
if (assetsModel.isDirectory(index) && !root.isExpanded(nRow)) {
|
||||
root.expand(nRow);
|
||||
for (let r = 0; r < root.rows; ++r) {
|
||||
let index = root.__modelIndex(r)
|
||||
if (assetsModel.isDirectory(index) && !root.isExpanded(r)) {
|
||||
root.expand(r)
|
||||
expandedAny = true
|
||||
}
|
||||
}
|
||||
@@ -352,15 +345,14 @@ TreeView {
|
||||
}
|
||||
|
||||
Keys.onRightPressed: {
|
||||
root.toggleDirectoryState("expand")
|
||||
root.expandFolder(true)
|
||||
}
|
||||
|
||||
Keys.onLeftPressed: {
|
||||
root.toggleDirectoryState("collapse")
|
||||
root.expandFolder(false)
|
||||
}
|
||||
|
||||
function toggleDirectoryState(action) {
|
||||
|
||||
function expandFolder(expand) {
|
||||
let index = root.currentFilePath ? assetsModel.indexForPath(root.currentFilePath)
|
||||
: root.__modelIndex(root.firstRow)
|
||||
|
||||
@@ -369,9 +361,11 @@ TreeView {
|
||||
|
||||
let row = root.rowAtIndex(index)
|
||||
|
||||
if (action === "expand")
|
||||
assetsModel.saveExpandState(root.currentFilePath, expand)
|
||||
|
||||
if (expand)
|
||||
root.expand(row)
|
||||
else if (action === "collapse")
|
||||
else
|
||||
root.collapse(row)
|
||||
}
|
||||
|
||||
|
@@ -177,8 +177,18 @@ bool AssetsLibraryModel::deleteFolderRecursively(const QModelIndex &folderIndex)
|
||||
{
|
||||
auto idx = mapToSource(folderIndex);
|
||||
bool ok = m_sourceFsModel->remove(idx);
|
||||
if (!ok)
|
||||
|
||||
if (ok) {
|
||||
Utils::FilePath parentPath = Utils::FilePath::fromString(filePath(folderIndex));
|
||||
const QStringList paths = s_folderExpandStateHash.keys();
|
||||
|
||||
for (const QString &path : paths) {
|
||||
if (Utils::FilePath::fromString(path).isChildOf(parentPath))
|
||||
s_folderExpandStateHash.remove(path);
|
||||
}
|
||||
} else {
|
||||
qWarning() << __FUNCTION__ << " could not remove folder recursively: " << m_sourceFsModel->filePath(idx);
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
@@ -205,6 +215,44 @@ bool AssetsLibraryModel::isSameOrDescendantPath(const QUrl &source, const QStrin
|
||||
return srcPath == targetPath || targetPath.isChildOf(srcPath);
|
||||
}
|
||||
|
||||
bool AssetsLibraryModel::folderExpandState(const QString &path) const
|
||||
{
|
||||
return s_folderExpandStateHash.value(path);
|
||||
}
|
||||
|
||||
void AssetsLibraryModel::initializeExpandState(const QString &path)
|
||||
{
|
||||
if (!s_folderExpandStateHash.contains(path))
|
||||
saveExpandState(path, true);
|
||||
}
|
||||
|
||||
void AssetsLibraryModel::saveExpandState(const QString &path, bool expand)
|
||||
{
|
||||
s_folderExpandStateHash.insert(path, expand);
|
||||
}
|
||||
|
||||
void AssetsLibraryModel::updateExpandPath(const Utils::FilePath &oldPath, const Utils::FilePath &newPath)
|
||||
{
|
||||
// update parent folder expand state
|
||||
bool value = s_folderExpandStateHash.take(oldPath.toFSPathString());
|
||||
saveExpandState(newPath.toFSPathString(), value);
|
||||
|
||||
const QStringList paths = s_folderExpandStateHash.keys();
|
||||
|
||||
for (const QString &path : paths) {
|
||||
Utils::FilePath childPath = Utils::FilePath::fromString(path);
|
||||
|
||||
// update subfolders expand states
|
||||
if (childPath.isChildOf(oldPath)) {
|
||||
QString relativePath = Utils::FilePath::calcRelativePath(path, oldPath.toFSPathString());
|
||||
Utils::FilePath newChildPath = newPath.pathAppended(relativePath);
|
||||
|
||||
value = s_folderExpandStateHash.take(path);
|
||||
saveExpandState(newChildPath.toFSPathString(), value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool AssetsLibraryModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
|
||||
{
|
||||
QString path = m_sourceFsModel->filePath(sourceParent);
|
||||
|
@@ -7,6 +7,7 @@
|
||||
|
||||
namespace Utils {
|
||||
class FileSystemWatcher;
|
||||
class FilePath;
|
||||
}
|
||||
|
||||
QT_FORWARD_DECLARE_CLASS(QFileSystemModel)
|
||||
@@ -51,6 +52,10 @@ public:
|
||||
Q_INVOKABLE bool allFilePathsAreTextures(const QStringList &filePaths) const;
|
||||
Q_INVOKABLE bool allFilePathsAreComposedEffects(const QStringList &filePaths) const;
|
||||
Q_INVOKABLE bool isSameOrDescendantPath(const QUrl &source, const QString &target) const;
|
||||
Q_INVOKABLE bool folderExpandState(const QString &path) const;
|
||||
Q_INVOKABLE void initializeExpandState(const QString &path);
|
||||
Q_INVOKABLE void saveExpandState(const QString &path, bool expand);
|
||||
void updateExpandPath(const Utils::FilePath &oldPath, const Utils::FilePath &newPath);
|
||||
|
||||
int columnCount(const QModelIndex &parent = QModelIndex()) const override
|
||||
{
|
||||
@@ -80,6 +85,7 @@ private:
|
||||
QFileSystemModel *m_sourceFsModel = nullptr;
|
||||
bool m_isEmpty = true;
|
||||
Utils::FileSystemWatcher *m_fileWatcher = nullptr;
|
||||
inline static QHash<QString, bool> s_folderExpandStateHash;
|
||||
};
|
||||
|
||||
} // namespace QmlDesigner
|
||||
|
@@ -427,11 +427,17 @@ void AssetsLibraryWidget::handleAssetsDrop(const QList<QUrl> &urls, const QStrin
|
||||
}
|
||||
}
|
||||
|
||||
if (!src.renameFile(dest) && src.isDir()) {
|
||||
QString message = tr("Failed to move folder \"%1\". "
|
||||
"The folder might contain subfolders or one of its files is in use.")
|
||||
.arg(src.fileName());
|
||||
Core::AsynchronousMessageBox::warning(tr("Folder move failure"), message);
|
||||
bool isDir = src.isDir();
|
||||
|
||||
if (src.renameFile(dest)) {
|
||||
if (isDir)
|
||||
m_assetsModel->updateExpandPath(src, dest);
|
||||
} else if (isDir) {
|
||||
Core::AsynchronousMessageBox::warning(
|
||||
tr("Folder move failure"),
|
||||
tr("Failed to move folder \"%1\". The folder might contain subfolders or one of its files is in use.")
|
||||
.arg(src.fileName())
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user