Skip to content

Commit 63ff487

Browse files
committed
Track Menu: close all menus with Left key, fix for menus with QWidgetActions
1 parent 7f6d72f commit 63ff487

3 files changed

Lines changed: 44 additions & 4 deletions

File tree

src/widget/wsearchrelatedtracksmenu.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,8 @@ void WSearchRelatedTracksMenu::addTriggerSearchAction(
9191
auto pAction = make_parented<QWidgetAction>(this);
9292
pAction->setDefaultWidget(pCheckBox.get());
9393
// While the checkbox is selected (via keyboard, not hovered by pointer)
94-
// pressing Space will toggle it whereas pressing Return triggers the action.
94+
// pressing Space will toggle it whereas pressing Return triggers the action
95+
// and closes the menu (see WTrackMenu).
9596
connect(pAction.get(),
9697
&QAction::triggered,
9798
this,

src/widget/wtrackmenu.cpp

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include <QCheckBox>
44
#include <QDialogButtonBox>
55
#include <QInputDialog>
6+
#include <QKeyEvent>
67
#include <QList>
78
#include <QListWidget>
89
#include <QModelIndex>
@@ -154,6 +155,32 @@ void WTrackMenu::closeEvent(QCloseEvent* event) {
154155
emit trackMenuVisible(false);
155156
}
156157

158+
bool WTrackMenu::eventFilter(QObject* pObj, QEvent* e) {
159+
// If a checkbox in a QWidgetAction is focused, Left/Right keys are translated
160+
// to Up/Down which prevents closing the submenus with Left key like in other
161+
// submenus.
162+
// We simply call hide() of the submenu if Left is pressed.
163+
// We ignore Right.
164+
// Don't continue (close track menu) if the checkbox is at the top level.
165+
if (pObj->parent() != this && e->type() == QEvent::KeyPress) {
166+
QCheckBox* pCB = qobject_cast<QCheckBox*>(pObj);
167+
QKeyEvent* pKE = static_cast<QKeyEvent*>(e);
168+
if (!pCB || !pKE) {
169+
return QObject::eventFilter(pObj, e);
170+
}
171+
if (pKE->key() == Qt::Key_Left) {
172+
VERIFY_OR_DEBUG_ASSERT(pCB->parentWidget()) {
173+
return QObject::eventFilter(pObj, e);
174+
}
175+
pCB->parentWidget()->hide();
176+
return true;
177+
} else if (pKE->key() == Qt::Key_Right) {
178+
return true;
179+
}
180+
}
181+
return QObject::eventFilter(pObj, e);
182+
}
183+
157184
void WTrackMenu::popup(const QPoint& pos, QAction* at) {
158185
if (isEmpty()) {
159186
return;
@@ -1411,11 +1438,19 @@ void WTrackMenu::slotPopulateSearchRelatedMenu() {
14111438
const auto pTrack = getFirstTrackPointer();
14121439
if (pTrack) {
14131440
// Ensure it's enabled, else we can't add actions.
1414-
VERIFY_OR_DEBUG_ASSERT(m_pSearchRelatedMenu->isEnabled()) {
1415-
m_pSearchRelatedMenu->setEnabled(true);
1416-
}
1441+
m_pSearchRelatedMenu->setEnabled(true);
14171442
m_pSearchRelatedMenu->addActionsForTrack(*pTrack);
14181443
}
1444+
if (!m_pSearchRelatedMenu->isEmpty()) {
1445+
// We're interested in keypress Qt::Key_Left, so use our
1446+
// event filter like we do for the crate checkboxes.
1447+
for (auto* pObj : m_pSearchRelatedMenu->children()) {
1448+
QCheckBox* pCB = qobject_cast<QCheckBox*>(pObj);
1449+
if (pCB) {
1450+
pCB->installEventFilter(this);
1451+
}
1452+
}
1453+
}
14191454
m_pSearchRelatedMenu->setEnabled(!m_pSearchRelatedMenu->isEmpty());
14201455
m_bSearchRelatedMenuLoaded = true;
14211456
}
@@ -1537,6 +1572,8 @@ void WTrackMenu::slotPopulateCrateMenu() {
15371572
m_pCrateMenu);
15381573
pCheckBox->setProperty("crateId", QVariant::fromValue(crate.getId()));
15391574
pCheckBox->setEnabled(!crate.isLocked());
1575+
// We're interested in keypress Qt::Key_Left
1576+
pCheckBox->installEventFilter(this);
15401577
// Strangely, the normal styling of QActions does not automatically
15411578
// apply to QWidgetActions. The :selected pseudo-state unfortunately
15421579
// does not work with QWidgetAction. :hover works for selecting items

src/widget/wtrackmenu.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,8 @@ class WTrackMenu : public QMenu {
113113
void slotRemoveFromDisk();
114114
const QString getDeckGroup() const;
115115

116+
bool eventFilter(QObject* pObj, QEvent* e) override;
117+
116118
signals:
117119
void loadTrackToPlayer(TrackPointer pTrack, const QString& group, bool play = false);
118120
void trackMenuVisible(bool visible);

0 commit comments

Comments
 (0)