Add option to hide folder structure in Visual Deck Storage (#5575)

This commit is contained in:
RickyRister 2025-02-07 07:36:24 -08:00 committed by GitHub
parent 9ec621a1ae
commit 2c6e7d4d3a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 150 additions and 43 deletions

View file

@ -10,14 +10,16 @@ VisualDeckStorageFolderDisplayWidget::VisualDeckStorageFolderDisplayWidget(
QWidget *parent, QWidget *parent,
VisualDeckStorageWidget *_visualDeckStorageWidget, VisualDeckStorageWidget *_visualDeckStorageWidget,
QString _filePath, QString _filePath,
bool canBeHidden) bool canBeHidden,
: QWidget(parent), visualDeckStorageWidget(_visualDeckStorageWidget), filePath(_filePath) bool _showFolders)
: QWidget(parent), showFolders(_showFolders), visualDeckStorageWidget(_visualDeckStorageWidget), filePath(_filePath)
{ {
layout = new QVBoxLayout(this); layout = new QVBoxLayout(this);
setLayout(layout); setLayout(layout);
header = new BannerWidget(this, ""); header = new BannerWidget(this, "");
header->setClickable(canBeHidden); header->setClickable(canBeHidden);
header->setHidden(!showFolders);
layout->addWidget(header); layout->addWidget(header);
container = new QWidget(this); container = new QWidget(this);
@ -63,10 +65,26 @@ void VisualDeckStorageFolderDisplayWidget::refreshUi()
header->setText(bannerText); header->setText(bannerText);
} }
static QStringList getAllFiles(const QString &filePath, bool recursive)
{
QStringList allFiles;
// QDirIterator with QDir::Files ensures only files are listed (no directories)
auto flags =
recursive ? QDirIterator::Subdirectories | QDirIterator::FollowSymlinks : QDirIterator::NoIteratorFlags;
QDirIterator it(filePath, QDir::Files, flags);
while (it.hasNext()) {
allFiles << it.next(); // Add each file path to the list
}
return allFiles;
}
void VisualDeckStorageFolderDisplayWidget::createWidgetsForFiles() void VisualDeckStorageFolderDisplayWidget::createWidgetsForFiles()
{ {
QList<DeckPreviewWidget *> allDecks; QList<DeckPreviewWidget *> allDecks;
for (const QString &file : getAllFiles()) { for (const QString &file : getAllFiles(filePath, !showFolders)) {
auto *display = new DeckPreviewWidget(flowWidget, visualDeckStorageWidget, file); auto *display = new DeckPreviewWidget(flowWidget, visualDeckStorageWidget, file);
connect(display, &DeckPreviewWidget::deckPreviewClicked, visualDeckStorageWidget, connect(display, &DeckPreviewWidget::deckPreviewClicked, visualDeckStorageWidget,
@ -121,14 +139,82 @@ bool VisualDeckStorageFolderDisplayWidget::checkVisibility()
return atLeastOneWidgetVisible; return atLeastOneWidgetVisible;
} }
static QStringList getAllSubFolders(const QString &filePath)
{
QStringList allFolders;
// QDirIterator with QDir::Files ensures only files are listed (no directories)
QDirIterator it(filePath, QDir::Dirs | QDir::NoDotAndDotDot);
while (it.hasNext()) {
allFolders << it.next(); // Add each file path to the list
}
return allFolders;
}
void VisualDeckStorageFolderDisplayWidget::createWidgetsForFolders() void VisualDeckStorageFolderDisplayWidget::createWidgetsForFolders()
{ {
for (const QString &dir : getAllSubFolders()) { if (!showFolders) {
auto *display = new VisualDeckStorageFolderDisplayWidget(this, visualDeckStorageWidget, dir, true); return;
}
for (const QString &dir : getAllSubFolders(filePath)) {
auto *display = new VisualDeckStorageFolderDisplayWidget(this, visualDeckStorageWidget, dir, true, showFolders);
containerLayout->addWidget(display); containerLayout->addWidget(display);
} }
} }
void VisualDeckStorageFolderDisplayWidget::updateShowFolders(bool enabled)
{
showFolders = enabled;
if (!showFolders) {
flattenFolderStructure();
} else {
// if setting was switched from disabled to enabled, we assume that there isn't any existing subfolders
createWidgetsForFiles();
createWidgetsForFolders();
}
header->setHidden(!showFolders);
}
/**
* Recursively gets all DeckPreviewWidgets in this folder and its subfolders
*/
static QList<DeckPreviewWidget *> getAllDecksRecursive(VisualDeckStorageFolderDisplayWidget *folder)
{
QList<DeckPreviewWidget *> allDecks;
if (auto *flowWidget = folder->getFlowWidget()) {
// Iterate through all DeckPreviewWidgets in this folder
allDecks << flowWidget->findChildren<DeckPreviewWidget *>();
}
for (auto *subFolder : folder->findChildren<VisualDeckStorageFolderDisplayWidget *>()) {
allDecks << getAllDecksRecursive(subFolder);
}
return allDecks;
}
/**
* Recursively steals all DeckPreviewWidgets from this widget's subfolders, and deletes all subfolders
*/
void VisualDeckStorageFolderDisplayWidget::flattenFolderStructure()
{
for (VisualDeckStorageFolderDisplayWidget *subFolder : findChildren<VisualDeckStorageFolderDisplayWidget *>()) {
// steal all DeckPreviewWidgets from the subfolder and all its subfolders
for (auto *deck : getAllDecksRecursive(subFolder)) {
flowWidget->addWidget(deck);
}
// delete the subfolder
subFolder->deleteLater();
}
}
QStringList VisualDeckStorageFolderDisplayWidget::gatherAllTagsFromFlowWidget() const QStringList VisualDeckStorageFolderDisplayWidget::gatherAllTagsFromFlowWidget() const
{ {
QStringList allTags; QStringList allTags;
@ -149,31 +235,3 @@ QStringList VisualDeckStorageFolderDisplayWidget::gatherAllTagsFromFlowWidget()
return allTags; return allTags;
} }
QStringList VisualDeckStorageFolderDisplayWidget::getAllFiles() const
{
QStringList allFiles;
// QDirIterator with QDir::Files ensures only files are listed (no directories)
QDirIterator it(filePath, QDir::Files);
while (it.hasNext()) {
allFiles << it.next(); // Add each file path to the list
}
return allFiles;
}
QStringList VisualDeckStorageFolderDisplayWidget::getAllSubFolders() const
{
QStringList allFolders;
// QDirIterator with QDir::Files ensures only files are listed (no directories)
QDirIterator it(filePath, QDir::Dirs | QDir::NoDotAndDotDot);
while (it.hasNext()) {
allFolders << it.next(); // Add each file path to the list
}
return allFolders;
}

View file

@ -15,13 +15,13 @@ public:
VisualDeckStorageFolderDisplayWidget(QWidget *parent, VisualDeckStorageFolderDisplayWidget(QWidget *parent,
VisualDeckStorageWidget *_visualDeckStorageWidget, VisualDeckStorageWidget *_visualDeckStorageWidget,
QString _filePath, QString _filePath,
bool canBeHidden); bool canBeHidden,
bool _showFolders);
void refreshUi(); void refreshUi();
void createWidgetsForFiles(); void createWidgetsForFiles();
void createWidgetsForFolders(); void createWidgetsForFolders();
void flattenFolderStructure();
QStringList gatherAllTagsFromFlowWidget() const; QStringList gatherAllTagsFromFlowWidget() const;
[[nodiscard]] QStringList getAllFiles() const;
[[nodiscard]] QStringList getAllSubFolders() const;
FlowWidget *getFlowWidget() const FlowWidget *getFlowWidget() const
{ {
return flowWidget; return flowWidget;
@ -30,8 +30,10 @@ public:
public slots: public slots:
void updateVisibility(); void updateVisibility();
bool checkVisibility(); bool checkVisibility();
void updateShowFolders(bool enabled);
private: private:
bool showFolders;
QVBoxLayout *layout; QVBoxLayout *layout;
VisualDeckStorageWidget *visualDeckStorageWidget; VisualDeckStorageWidget *visualDeckStorageWidget;
QString filePath; QString filePath;

View file

@ -23,6 +23,7 @@ VisualDeckStorageWidget::VisualDeckStorageWidget(QWidget *parent) : QWidget(pare
layout->setContentsMargins(9, 0, 9, 5); layout->setContentsMargins(9, 0, 9, 5);
setLayout(layout); setLayout(layout);
// search bar row
searchAndSortLayout = new QHBoxLayout(this); searchAndSortLayout = new QHBoxLayout(this);
searchAndSortLayout->setSpacing(3); searchAndSortLayout->setSpacing(3);
searchAndSortLayout->setContentsMargins(9, 0, 9, 0); searchAndSortLayout->setContentsMargins(9, 0, 9, 0);
@ -30,26 +31,42 @@ VisualDeckStorageWidget::VisualDeckStorageWidget(QWidget *parent) : QWidget(pare
deckPreviewColorIdentityFilterWidget = new DeckPreviewColorIdentityFilterWidget(this); deckPreviewColorIdentityFilterWidget = new DeckPreviewColorIdentityFilterWidget(this);
sortWidget = new VisualDeckStorageSortWidget(this); sortWidget = new VisualDeckStorageSortWidget(this);
searchWidget = new VisualDeckStorageSearchWidget(this); searchWidget = new VisualDeckStorageSearchWidget(this);
tagFilterWidget = new VisualDeckStorageTagFilterWidget(this);
searchAndSortLayout->addWidget(deckPreviewColorIdentityFilterWidget); searchAndSortLayout->addWidget(deckPreviewColorIdentityFilterWidget);
searchAndSortLayout->addWidget(sortWidget); searchAndSortLayout->addWidget(sortWidget);
searchAndSortLayout->addWidget(searchWidget); searchAndSortLayout->addWidget(searchWidget);
layout->addLayout(searchAndSortLayout);
layout->addWidget(tagFilterWidget); // checkbox row
QHBoxLayout *checkBoxLayout = new QHBoxLayout(this);
checkBoxLayout->setContentsMargins(9, 0, 9, 0);
showFoldersCheckBox = new QCheckBox(this);
showFoldersCheckBox->setChecked(SettingsCache::instance().getVisualDeckStorageShowFolders());
connect(showFoldersCheckBox, &QCheckBox::QT_STATE_CHANGED, &SettingsCache::instance(),
&SettingsCache::setVisualDeckStorageShowFolders);
checkBoxLayout->addWidget(showFoldersCheckBox);
checkBoxLayout->addStretch();
// tag filter box
tagFilterWidget = new VisualDeckStorageTagFilterWidget(this);
// card size slider
cardSizeWidget = new CardSizeWidget(this, nullptr, SettingsCache::instance().getVisualDeckStorageCardSize()); cardSizeWidget = new CardSizeWidget(this, nullptr, SettingsCache::instance().getVisualDeckStorageCardSize());
// deck area
scrollArea = new QScrollArea(this); scrollArea = new QScrollArea(this);
scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded); scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
folderWidget = new VisualDeckStorageFolderDisplayWidget(this, this, SettingsCache::instance().getDeckPath(), false);
scrollArea->setWidget(folderWidget); scrollArea->setWidget(folderWidget);
scrollArea->setWidgetResizable(true); scrollArea->setWidgetResizable(true);
// putting everything together
layout->addLayout(searchAndSortLayout);
layout->addLayout(checkBoxLayout);
layout->addWidget(tagFilterWidget);
layout->addWidget(scrollArea); layout->addWidget(scrollArea);
layout->addWidget(cardSizeWidget); layout->addWidget(cardSizeWidget);
connect(CardDatabaseManager::getInstance(), &CardDatabase::cardDatabaseLoadingFinished, this, connect(CardDatabaseManager::getInstance(), &CardDatabase::cardDatabaseLoadingFinished, this,
@ -90,6 +107,8 @@ void VisualDeckStorageWidget::resizeEvent(QResizeEvent *event)
void VisualDeckStorageWidget::retranslateUi() void VisualDeckStorageWidget::retranslateUi()
{ {
databaseLoadIndicator->setText(tr("Loading database ...")); databaseLoadIndicator->setText(tr("Loading database ..."));
showFoldersCheckBox->setText(tr("Show Folders"));
} }
void VisualDeckStorageWidget::deckPreviewClickedEvent(QMouseEvent *event, DeckPreviewWidget *instance) void VisualDeckStorageWidget::deckPreviewClickedEvent(QMouseEvent *event, DeckPreviewWidget *instance)
@ -105,7 +124,12 @@ void VisualDeckStorageWidget::deckPreviewDoubleClickedEvent(QMouseEvent *event,
void VisualDeckStorageWidget::createRootFolderWidget() void VisualDeckStorageWidget::createRootFolderWidget()
{ {
folderWidget = new VisualDeckStorageFolderDisplayWidget(this, this, SettingsCache::instance().getDeckPath(), false); folderWidget = new VisualDeckStorageFolderDisplayWidget(this, this, SettingsCache::instance().getDeckPath(), false,
showFoldersCheckBox->isChecked());
connect(showFoldersCheckBox, &QCheckBox::QT_STATE_CHANGED, folderWidget,
&VisualDeckStorageFolderDisplayWidget::updateShowFolders);
scrollArea->setWidget(folderWidget); scrollArea->setWidget(folderWidget);
scrollArea->widget()->setMaximumWidth(scrollArea->viewport()->width()); scrollArea->widget()->setMaximumWidth(scrollArea->viewport()->width());
scrollArea->widget()->adjustSize(); scrollArea->widget()->adjustSize();

View file

@ -11,6 +11,7 @@
#include "visual_deck_storage_sort_widget.h" #include "visual_deck_storage_sort_widget.h"
#include "visual_deck_storage_tag_filter_widget.h" #include "visual_deck_storage_tag_filter_widget.h"
#include <QCheckBox>
#include <QFileSystemModel> #include <QFileSystemModel>
class VisualDeckStorageSearchWidget; class VisualDeckStorageSearchWidget;
@ -56,6 +57,9 @@ private:
VisualDeckStorageSortWidget *sortWidget; VisualDeckStorageSortWidget *sortWidget;
VisualDeckStorageSearchWidget *searchWidget; VisualDeckStorageSearchWidget *searchWidget;
DeckPreviewColorIdentityFilterWidget *deckPreviewColorIdentityFilterWidget; DeckPreviewColorIdentityFilterWidget *deckPreviewColorIdentityFilterWidget;
QCheckBox *showFoldersCheckBox;
QScrollArea *scrollArea; QScrollArea *scrollArea;
VisualDeckStorageFolderDisplayWidget *folderWidget; VisualDeckStorageFolderDisplayWidget *folderWidget;
}; };

View file

@ -266,6 +266,7 @@ SettingsCache::SettingsCache()
settings->value("cards/printingselectornavigationbuttonsvisible", true).toBool(); settings->value("cards/printingselectornavigationbuttonsvisible", true).toBool();
visualDeckStorageCardSize = settings->value("cards/visualdeckstoragecardsize", 100).toInt(); visualDeckStorageCardSize = settings->value("cards/visualdeckstoragecardsize", 100).toInt();
visualDeckStorageSortingOrder = settings->value("interface/visualdeckstoragesortingorder", 0).toInt(); visualDeckStorageSortingOrder = settings->value("interface/visualdeckstoragesortingorder", 0).toInt();
visualDeckStorageShowFolders = settings->value("interface/visualdeckstorageshowfolders", true).toBool();
visualDeckStorageDrawUnusedColorIdentities = visualDeckStorageDrawUnusedColorIdentities =
settings->value("interface/visualdeckstoragedrawunusedcoloridentities", true).toBool(); settings->value("interface/visualdeckstoragedrawunusedcoloridentities", true).toBool();
visualDeckStorageUnusedColorIdentitiesOpacity = visualDeckStorageUnusedColorIdentitiesOpacity =
@ -678,6 +679,12 @@ void SettingsCache::setVisualDeckStorageSortingOrder(int _visualDeckStorageSorti
settings->setValue("interface/visualdeckstoragesortingorder", visualDeckStorageSortingOrder); settings->setValue("interface/visualdeckstoragesortingorder", visualDeckStorageSortingOrder);
} }
void SettingsCache::setVisualDeckStorageShowFolders(QT_STATE_CHANGED_T value)
{
visualDeckStorageShowFolders = value;
settings->setValue("interface/visualdeckstorageshowfolders", visualDeckStorageShowFolders);
}
void SettingsCache::setVisualDeckStorageCardSize(int _visualDeckStorageCardSize) void SettingsCache::setVisualDeckStorageCardSize(int _visualDeckStorageCardSize)
{ {
visualDeckStorageCardSize = _visualDeckStorageCardSize; visualDeckStorageCardSize = _visualDeckStorageCardSize;

View file

@ -131,6 +131,7 @@ private:
bool printingSelectorCardSizeSliderVisible; bool printingSelectorCardSizeSliderVisible;
bool printingSelectorNavigationButtonsVisible; bool printingSelectorNavigationButtonsVisible;
int visualDeckStorageSortingOrder; int visualDeckStorageSortingOrder;
bool visualDeckStorageShowFolders;
int visualDeckStorageCardSize; int visualDeckStorageCardSize;
bool visualDeckStorageDrawUnusedColorIdentities; bool visualDeckStorageDrawUnusedColorIdentities;
int visualDeckStorageUnusedColorIdentitiesOpacity; int visualDeckStorageUnusedColorIdentitiesOpacity;
@ -416,6 +417,10 @@ public:
{ {
return visualDeckStorageSortingOrder; return visualDeckStorageSortingOrder;
} }
bool getVisualDeckStorageShowFolders() const
{
return visualDeckStorageShowFolders;
}
int getVisualDeckStorageCardSize() const int getVisualDeckStorageCardSize() const
{ {
return visualDeckStorageCardSize; return visualDeckStorageCardSize;
@ -761,6 +766,7 @@ public slots:
void setPrintingSelectorCardSizeSliderVisible(QT_STATE_CHANGED_T _cardSizeSliderVisible); void setPrintingSelectorCardSizeSliderVisible(QT_STATE_CHANGED_T _cardSizeSliderVisible);
void setPrintingSelectorNavigationButtonsVisible(QT_STATE_CHANGED_T _navigationButtonsVisible); void setPrintingSelectorNavigationButtonsVisible(QT_STATE_CHANGED_T _navigationButtonsVisible);
void setVisualDeckStorageSortingOrder(int _visualDeckStorageSortingOrder); void setVisualDeckStorageSortingOrder(int _visualDeckStorageSortingOrder);
void setVisualDeckStorageShowFolders(QT_STATE_CHANGED_T value);
void setVisualDeckStorageCardSize(int _visualDeckStorageCardSize); void setVisualDeckStorageCardSize(int _visualDeckStorageCardSize);
void setVisualDeckStorageDrawUnusedColorIdentities(QT_STATE_CHANGED_T _visualDeckStorageDrawUnusedColorIdentities); void setVisualDeckStorageDrawUnusedColorIdentities(QT_STATE_CHANGED_T _visualDeckStorageDrawUnusedColorIdentities);
void setVisualDeckStorageUnusedColorIdentitiesOpacity(int _visualDeckStorageUnusedColorIdentitiesOpacity); void setVisualDeckStorageUnusedColorIdentitiesOpacity(int _visualDeckStorageUnusedColorIdentitiesOpacity);

View file

@ -211,6 +211,9 @@ void SettingsCache::setPrintingSelectorNavigationButtonsVisible(QT_STATE_CHANGED
void SettingsCache::setVisualDeckStorageSortingOrder(int /* _visualDeckStorageSortingOrder */) void SettingsCache::setVisualDeckStorageSortingOrder(int /* _visualDeckStorageSortingOrder */)
{ {
} }
void SettingsCache::setVisualDeckStorageShowFolders(QT_STATE_CHANGED_T /* value */)
{
}
void SettingsCache::setVisualDeckStorageCardSize(int /* _visualDeckStorageCardSize */) void SettingsCache::setVisualDeckStorageCardSize(int /* _visualDeckStorageCardSize */)
{ {
} }

View file

@ -215,6 +215,9 @@ void SettingsCache::setPrintingSelectorNavigationButtonsVisible(QT_STATE_CHANGED
void SettingsCache::setVisualDeckStorageSortingOrder(int /* _visualDeckStorageSortingOrder */) void SettingsCache::setVisualDeckStorageSortingOrder(int /* _visualDeckStorageSortingOrder */)
{ {
} }
void SettingsCache::setVisualDeckStorageShowFolders(QT_STATE_CHANGED_T /* value */)
{
}
void SettingsCache::setVisualDeckStorageCardSize(int /* _visualDeckStorageCardSize */) void SettingsCache::setVisualDeckStorageCardSize(int /* _visualDeckStorageCardSize */)
{ {
} }