|
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> |
@@ -154,6 +155,32 @@ void WTrackMenu::closeEvent(QCloseEvent* event) { |
154 | 155 | emit trackMenuVisible(false); |
155 | 156 | } |
156 | 157 |
|
| 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 | + |
157 | 184 | void WTrackMenu::popup(const QPoint& pos, QAction* at) { |
158 | 185 | if (isEmpty()) { |
159 | 186 | return; |
@@ -1411,11 +1438,19 @@ void WTrackMenu::slotPopulateSearchRelatedMenu() { |
1411 | 1438 | const auto pTrack = getFirstTrackPointer(); |
1412 | 1439 | if (pTrack) { |
1413 | 1440 | // 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); |
1417 | 1442 | m_pSearchRelatedMenu->addActionsForTrack(*pTrack); |
1418 | 1443 | } |
| 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 | + } |
1419 | 1454 | m_pSearchRelatedMenu->setEnabled(!m_pSearchRelatedMenu->isEmpty()); |
1420 | 1455 | m_bSearchRelatedMenuLoaded = true; |
1421 | 1456 | } |
@@ -1537,6 +1572,8 @@ void WTrackMenu::slotPopulateCrateMenu() { |
1537 | 1572 | m_pCrateMenu); |
1538 | 1573 | pCheckBox->setProperty("crateId", QVariant::fromValue(crate.getId())); |
1539 | 1574 | pCheckBox->setEnabled(!crate.isLocked()); |
| 1575 | + // We're interested in keypress Qt::Key_Left |
| 1576 | + pCheckBox->installEventFilter(this); |
1540 | 1577 | // Strangely, the normal styling of QActions does not automatically |
1541 | 1578 | // apply to QWidgetActions. The :selected pseudo-state unfortunately |
1542 | 1579 | // does not work with QWidgetAction. :hover works for selecting items |
|
0 commit comments