|
3 | 3 | #include <QCheckBox> |
4 | 4 | #include <QDialogButtonBox> |
5 | 5 | #include <QInputDialog> |
| 6 | +#include <QKeyEvent> |
6 | 7 | #include <QList> |
7 | 8 | #include <QListWidget> |
8 | 9 | #include <QModelIndex> |
@@ -161,6 +162,32 @@ void WTrackMenu::closeEvent(QCloseEvent* event) { |
161 | 162 | emit trackMenuVisible(false); |
162 | 163 | } |
163 | 164 |
|
| 165 | +bool WTrackMenu::eventFilter(QObject* pObj, QEvent* e) { |
| 166 | + // If a checkbox in a QWidgetAction is focused, Left/Right keys are translated |
| 167 | + // to Up/Down which prevents closing the submenus with Left key like in other |
| 168 | + // submenus. |
| 169 | + // We simply call hide() of the submenu if Left is pressed. |
| 170 | + // We ignore Right. |
| 171 | + // Don't continue (close track menu) if the checkbox is at the top level. |
| 172 | + if (pObj->parent() && pObj->parent() != this && e->type() == QEvent::KeyPress) { |
| 173 | + QCheckBox* pCB = qobject_cast<QCheckBox*>(pObj); |
| 174 | + QKeyEvent* pKE = static_cast<QKeyEvent*>(e); |
| 175 | + if (!pCB || !pKE) { |
| 176 | + return QObject::eventFilter(pObj, e); |
| 177 | + } |
| 178 | + if (pKE->key() == Qt::Key_Left) { |
| 179 | + VERIFY_OR_DEBUG_ASSERT(pCB->parentWidget()) { |
| 180 | + return QObject::eventFilter(pObj, e); |
| 181 | + } |
| 182 | + pCB->parentWidget()->hide(); |
| 183 | + return true; |
| 184 | + } else if (pKE->key() == Qt::Key_Right) { |
| 185 | + return true; |
| 186 | + } |
| 187 | + } |
| 188 | + return QObject::eventFilter(pObj, e); |
| 189 | +} |
| 190 | + |
164 | 191 | void WTrackMenu::popup(const QPoint& pos, QAction* at) { |
165 | 192 | if (isEmpty()) { |
166 | 193 | return; |
@@ -258,6 +285,16 @@ void WTrackMenu::createMenus() { |
258 | 285 | m_pSearchRelatedMenu->setEnabled( |
259 | 286 | !m_pSearchRelatedMenu->isEmpty()); |
260 | 287 | m_bSearchRelatedMenuLoaded = true; |
| 288 | + if (!m_pSearchRelatedMenu->isEmpty()) { |
| 289 | + // We're interested in keypress Qt::Key_Left, so use our |
| 290 | + // event filter like we do for the crate checkboxes. |
| 291 | + for (auto* pObj : m_pSearchRelatedMenu->children()) { |
| 292 | + QCheckBox* pCB = qobject_cast<QCheckBox*>(pObj); |
| 293 | + if (pCB) { |
| 294 | + pCB->installEventFilter(this); |
| 295 | + } |
| 296 | + } |
| 297 | + } |
261 | 298 | }); |
262 | 299 | connect(m_pSearchRelatedMenu, |
263 | 300 | &WSearchRelatedTracksMenu::triggerSearch, |
@@ -1651,6 +1688,8 @@ void WTrackMenu::slotPopulateCrateMenu() { |
1651 | 1688 | m_pCrateMenu); |
1652 | 1689 | pCheckBox->setProperty("crateId", QVariant::fromValue(crate.getId())); |
1653 | 1690 | pCheckBox->setEnabled(!crate.isLocked()); |
| 1691 | + // We're interested in keypress Qt::Key_Left |
| 1692 | + pCheckBox->installEventFilter(this); |
1654 | 1693 | // Strangely, the normal styling of QActions does not automatically |
1655 | 1694 | // apply to QWidgetActions. The :selected pseudo-state unfortunately |
1656 | 1695 | // does not work with QWidgetAction. :hover works for selecting items |
|
0 commit comments