Skip to content

Commit

Permalink
WTrackMenu: Filtering: Add a text box for filtering the crates to the…
Browse files Browse the repository at this point in the history
… crates submenu
  • Loading branch information
cr7pt0gr4ph7 committed Oct 16, 2024
1 parent fdcc0ee commit 0844be7
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 0 deletions.
24 changes: 24 additions & 0 deletions src/util/reverse_iterable.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#pragma once

#include <iterator>

// Reversed iterable to for use in range-for loops.
template<typename T>
struct reverse_iterable {
T& iterable;
};

template<typename T>
auto begin(reverse_iterable<T> w) {
return std::rbegin(w.iterable);
}

template<typename T>
auto end(reverse_iterable<T> w) {
return std::rend(w.iterable);
}

template<typename T>
reverse_iterable<T> make_reverse_iterable(T&& iterable) {
return {iterable};
}
43 changes: 43 additions & 0 deletions src/widget/wtrackmenu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@
#include <QCheckBox>
#include <QDialogButtonBox>
#include <QInputDialog>
#include <QLineEdit>
#include <QList>
#include <QListWidget>
#include <QModelIndex>
#include <QVBoxLayout>
#include <QWidgetAction>

#include "analyzer/analyzerscheduledtrack.h"
#include "analyzer/analyzersilence.h"
Expand Down Expand Up @@ -48,6 +50,7 @@
#include "widget/wfindonwebmenu.h"
#include "widget/wsearchrelatedtracksmenu.h"
// WStarRating is required for DlgTrackInfo
#include "util/reverse_iterable.h"
#include "widget/wstarrating.h"
#include "widget/wstarratingaction.h"

Expand Down Expand Up @@ -378,6 +381,18 @@ void WTrackMenu::createActions() {
}

if (featureIsEnabled(Feature::Crate)) {
auto placeholderText = tr("Start typing to filter crates...");
m_pFilterCratesEdit = new QLineEdit(this);
m_pFilterCratesEdit->setPlaceholderText(placeholderText);
m_pFilterCratesEdit->setToolTip(placeholderText);
connect(m_pFilterCratesEdit,
&QLineEdit::textChanged,
this,
&WTrackMenu::slotCrateFilterTextChanged);

m_pFilterCratesAct = new QWidgetAction(this);
m_pFilterCratesAct->setDefaultWidget(m_pFilterCratesEdit);

m_pAddToNewCrateAct = new QAction(tr("Add to New Crate"), this);
connect(m_pAddToNewCrateAct,
&QAction::triggered,
Expand Down Expand Up @@ -1486,6 +1501,7 @@ void WTrackMenu::slotPopulateCrateMenu() {
return;
}
m_pCrateMenu->clear();
m_pCrateMenu->addAction(m_pFilterCratesAct);
const TrackIdList trackIds = getTrackIds();

CrateSummarySelectResult allCrates(
Expand Down Expand Up @@ -1555,6 +1571,33 @@ void WTrackMenu::slotPopulateCrateMenu() {
m_bCrateMenuLoaded = true;
}

void WTrackMenu::slotCrateFilterTextChanged(const QString& newText) {
// Iterate in reverse order so that we can hide sections
// that do not contain any visible items.
bool sectionHasVisibleItems = false;
for (QAction* pAction : make_reverse_iterable(m_pCrateMenu->actions())) {
auto crateId = pAction->property("crateId").value<CrateId>();
auto folderId = pAction->property("folderId").value<CrateFolderId>();

if (crateId.isValid()) {
// pAction has a valid crateId property => This actions represents a crate checkbox
// Visibility depends on whether it matches the specified search text.
// TODO(cr7pt0gr4ph7): Also match against the folder path?
// TODO(cr7pt0gr4ph7): Check whether we use the correct text comparison mode
bool isVisible = newText.isEmpty() || pAction->text().contains(newText);
pAction->setVisible(isVisible);
sectionHasVisibleItems |= isVisible;
} else if (folderId.isValid()) {
// pAction has a valid folderId => This action represents a folder section
// Visibility depends on the visibility of the crates contained in this folder.
pAction->setVisible(sectionHasVisibleItems);
sectionHasVisibleItems = false;
} else {
// Other actions, just ignore these.
}
}
}

void WTrackMenu::updateSelectionCrates(QWidget* pWidget) {
auto* pCheckBox = qobject_cast<QCheckBox*>(pWidget);
VERIFY_OR_DEBUG_ASSERT(pCheckBox) {
Expand Down
5 changes: 5 additions & 0 deletions src/widget/wtrackmenu.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ class DlgTrackInfoMulti;
//class DlgDeleteFilesConfirmation;
class ExternalTrackCollection;
class Library;
class QLineEdit;
class QWidgetAction;
class TrackModel;
class WColorPickerAction;
class WCoverArtMenu;
Expand Down Expand Up @@ -163,6 +165,7 @@ class WTrackMenu : public QMenu {
// Playlist and crate
void slotPopulatePlaylistMenu();
void slotPopulateCrateMenu();
void slotCrateFilterTextChanged(const QString& newText);
void addSelectionToNewCrate();

// Auto DJ
Expand Down Expand Up @@ -270,6 +273,8 @@ class WTrackMenu : public QMenu {
#endif

// Crate Submenu Actions
QWidgetAction* m_pFilterCratesAct{};
QLineEdit* m_pFilterCratesEdit{};
QAction* m_pAddToNewCrateAct{};

// Update ReplayGain from Track
Expand Down

0 comments on commit 0844be7

Please sign in to comment.