From 9e6b54357f899c7e248ed1ff33273baf3dce305b Mon Sep 17 00:00:00 2001 From: ronso0 Date: Sun, 3 Mar 2024 23:16:55 +0100 Subject: [PATCH 1/2] BrowseFeature: add action to refresh directory tree remove cached 'hasChildren' state for all sub-dirs in order to allow expanding items that have sub-dirs added after the items have been shown the first time. --- src/library/browse/browsefeature.cpp | 81 ++++++++++++++++++++-------- src/library/browse/browsefeature.h | 3 ++ 2 files changed, 61 insertions(+), 23 deletions(-) diff --git a/src/library/browse/browsefeature.cpp b/src/library/browse/browsefeature.cpp index 180c67008d0..05a6a3baedf 100644 --- a/src/library/browse/browsefeature.cpp +++ b/src/library/browse/browsefeature.cpp @@ -73,6 +73,12 @@ BrowseFeature::BrowseFeature( this, &BrowseFeature::slotAddToLibrary); + m_pRefreshDirTreeAction = new QAction(tr("Refresh directory tree"), this); + connect(m_pRefreshDirTreeAction, + &QAction::triggered, + this, + &BrowseFeature::slotRefreshDirectoryTree); + m_proxyModel.setFilterCaseSensitivity(Qt::CaseInsensitive); m_proxyModel.setSortCaseSensitivity(Qt::CaseInsensitive); // BrowseThread sets the Qt::UserRole of every QStandardItem to the sort key @@ -226,6 +232,24 @@ void BrowseFeature::slotRemoveQuickLink() { saveQuickLinks(); } +void BrowseFeature::slotRefreshDirectoryTree() { + if (!m_pLastRightClickedItem) { + return; + } + + const auto* pItem = m_pLastRightClickedItem; + if (!pItem->getData().isValid()) { + return; + } + + const QString path = pItem->getData().toString(); + m_pSidebarModel->removeChildDirsFromCache(QStringList{path}); + + // Update child items + const QModelIndex index = m_pSidebarModel->index(pItem->parentRow(), 0); + onLazyChildExpandation(index); +} + TreeItemModel* BrowseFeature::sidebarModel() const { return m_pSidebarModel; } @@ -323,6 +347,7 @@ void BrowseFeature::onRightClickChild(const QPoint& globalPos, const QModelIndex menu.addAction(m_pAddQuickLinkAction); menu.addAction(m_pAddtoLibraryAction); + menu.addAction(m_pRefreshDirTreeAction); menu.exec(globalPos); onLazyChildExpandation(index); } @@ -423,34 +448,44 @@ void BrowseFeature::onLazyChildExpandation(const QModelIndex& index) { #endif folders = createRemovableDevices(); } else { - // we assume that the path refers to a folder in the file system - // populate children - const auto dirAccess = mixxx::FileAccess(mixxx::FileInfo(path)); + folders = getChildDirectoryItems(path); + } - QFileInfoList all = dirAccess.info().toQDir().entryInfoList( - QDir::Dirs | QDir::NoDotAndDotDot); + if (!folders.empty()) { + m_pSidebarModel->insertTreeItemRows(std::move(folders), 0, index); + } +} + +std::vector> BrowseFeature::getChildDirectoryItems( + const QString& path) const { + std::vector> items; + + if (path.isEmpty()) { + return items; + } + // we assume that the path refers to a folder in the file system + // populate children + const auto dirAccess = mixxx::FileAccess(mixxx::FileInfo(path)); - // loop through all the item and construct the children - foreach (QFileInfo one, all) { - // Skip folders that end with .app on OS X + QFileInfoList all = dirAccess.info().toQDir().entryInfoList( + QDir::Dirs | QDir::NoDotAndDotDot); + + // loop through all the item and construct the children + foreach (QFileInfo one, all) { + // Skip folders that end with .app on OS X #if defined(__APPLE__) - if (one.isDir() && one.fileName().endsWith(".app")) - continue; + if (one.isDir() && one.fileName().endsWith(".app")) + continue; #endif - // We here create new items for the sidebar models - // Once the items are added to the TreeItemModel, - // the models takes ownership of them and ensures their deletion - folders.push_back(std::make_unique( - one.fileName(), - QVariant(one.absoluteFilePath() + QStringLiteral("/")))); - } - } - // we need to check here if subfolders are found - // On Ubuntu 10.04, otherwise, this will draw an icon although the folder - // has no subfolders - if (!folders.empty()) { - m_pSidebarModel->insertTreeItemRows(std::move(folders), 0, index); + // We here create new items for the sidebar models + // Once the items are added to the TreeItemModel, + // the models takes ownership of them and ensures their deletion + items.push_back(std::make_unique( + one.fileName(), + QVariant(one.absoluteFilePath() + QStringLiteral("/")))); } + + return items; } QString BrowseFeature::getRootViewHtml() const { diff --git a/src/library/browse/browsefeature.h b/src/library/browse/browsefeature.h index d7c0d5064ec..eb363715edc 100644 --- a/src/library/browse/browsefeature.h +++ b/src/library/browse/browsefeature.h @@ -42,6 +42,7 @@ class BrowseFeature : public LibraryFeature { void slotAddQuickLink(); void slotRemoveQuickLink(); void slotAddToLibrary(); + void slotRefreshDirectoryTree(); void activate() override; void activateChild(const QModelIndex& index) override; void onRightClickChild(const QPoint& globalPos, const QModelIndex& index) override; @@ -58,6 +59,7 @@ class BrowseFeature : public LibraryFeature { QString getRootViewHtml() const; QString extractNameFromPath(const QString& spath); QStringList getDefaultQuickLinks() const; + std::vector> getChildDirectoryItems(const QString& path) const; void saveQuickLinks(); void loadQuickLinks(); @@ -69,6 +71,7 @@ class BrowseFeature : public LibraryFeature { QAction* m_pAddQuickLinkAction; QAction* m_pRemoveQuickLinkAction; QAction* m_pAddtoLibraryAction; + QAction* m_pRefreshDirTreeAction; // Caution: Make sure this is reset whenever the library tree is updated, // so that the internalPointer() does not become dangling From fb12fc179c50f02291d070f1340320a27e2d56f6 Mon Sep 17 00:00:00 2001 From: ronso0 Date: Thu, 2 May 2024 14:33:55 +0200 Subject: [PATCH 2/2] BrowseFeature: add Refresh action to QuickLinks --- src/library/browse/browsefeature.cpp | 30 ++++++++++++++-------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/library/browse/browsefeature.cpp b/src/library/browse/browsefeature.cpp index 05a6a3baedf..edf0cda2aac 100644 --- a/src/library/browse/browsefeature.cpp +++ b/src/library/browse/browsefeature.cpp @@ -327,29 +327,29 @@ void BrowseFeature::onRightClickChild(const QPoint& globalPos, const QModelIndex QMenu menu(m_pSidebarWidget); - // If this a QuickLink show only the Remove action if (item->parent()->getData().toString() == QUICK_LINK_NODE) { + // This is a QuickLink menu.addAction(m_pRemoveQuickLinkAction); + menu.addAction(m_pRefreshDirTreeAction); menu.exec(globalPos); onLazyChildExpandation(index); return; } - // If path is in the QuickLinks list show only the Remove action - foreach (const QString& str, m_quickLinkList) { - if (str == path) { - menu.addAction(m_pRemoveQuickLinkAction); - menu.exec(globalPos); - onLazyChildExpandation(index); - return; - } - } + if (m_quickLinkList.contains(path)) { + // Path is in the Quick Link list + menu.addAction(m_pRemoveQuickLinkAction); + menu.addAction(m_pRefreshDirTreeAction); + menu.exec(globalPos); + onLazyChildExpandation(index); + return; + } - menu.addAction(m_pAddQuickLinkAction); - menu.addAction(m_pAddtoLibraryAction); - menu.addAction(m_pRefreshDirTreeAction); - menu.exec(globalPos); - onLazyChildExpandation(index); + menu.addAction(m_pAddQuickLinkAction); + menu.addAction(m_pAddtoLibraryAction); + menu.addAction(m_pRefreshDirTreeAction); + menu.exec(globalPos); + onLazyChildExpandation(index); } namespace {