SelectDialog: support shortcuts

This commit is contained in:
Le Tan 2021-07-25 09:10:48 +08:00
parent 7fc7481cfb
commit 87932751b4
4 changed files with 82 additions and 20 deletions

View File

@ -3,12 +3,22 @@
#include <QtWidgets> #include <QtWidgets>
#include <utils/widgetutils.h> #include <utils/widgetutils.h>
#include <utils/iconutils.h>
#include <utils/utils.h>
#include <core/thememgr.h>
#include <core/vnotex.h>
using namespace vnotex; using namespace vnotex;
const QChar SelectDialog::c_cancelShortcut = QLatin1Char('z');
SelectDialog::SelectDialog(const QString &p_title, QWidget *p_parent) SelectDialog::SelectDialog(const QString &p_title, QWidget *p_parent)
: QDialog(p_parent) : QDialog(p_parent)
{ {
const auto &themeMgr = VNoteX::getInst().getThemeMgr();
m_shortcutIconForeground = themeMgr.paletteColor(QStringLiteral("widgets#quickselector#item_icon#fg"));
m_shortcutIconBorder = themeMgr.paletteColor(QStringLiteral("widgets#quickselector#item_icon#border"));
setupUI(p_title); setupUI(p_title);
} }
@ -24,12 +34,19 @@ void SelectDialog::setupUI(const QString &p_title)
connect(m_list, &QListWidget::itemActivated, connect(m_list, &QListWidget::itemActivated,
this, &SelectDialog::selectionChosen); this, &SelectDialog::selectionChosen);
m_list->installEventFilter(this);
// Add cancel item. // Add cancel item.
QListWidgetItem *cancelItem = new QListWidgetItem(tr("Cancel")); {
const auto icon = IconUtils::drawTextIcon(c_cancelShortcut, m_shortcutIconForeground, m_shortcutIconBorder);
QListWidgetItem *cancelItem = new QListWidgetItem(icon, tr("Cancel"));
cancelItem->setData(Qt::UserRole, CANCEL_ID); cancelItem->setData(Qt::UserRole, CANCEL_ID);
m_shortcuts.insert(c_cancelShortcut, cancelItem);
m_list->addItem(cancelItem); m_list->addItem(cancelItem);
m_list->setCurrentRow(0); m_list->setCurrentRow(0);
}
mainLayout->addWidget(m_list); mainLayout->addWidget(m_list);
@ -40,8 +57,19 @@ void SelectDialog::addSelection(const QString &p_selectStr, int p_selectID)
{ {
Q_ASSERT(p_selectID >= 0); Q_ASSERT(p_selectID >= 0);
QListWidgetItem *item = new QListWidgetItem(p_selectStr); QChar shortcut;
if (m_nextShortcut < c_cancelShortcut) {
shortcut = m_nextShortcut;
m_nextShortcut = m_nextShortcut.toLatin1() + 1;
}
const auto icon = IconUtils::drawTextIcon(shortcut, m_shortcutIconForeground, m_shortcutIconBorder);
QListWidgetItem *item = new QListWidgetItem(icon, p_selectStr);
item->setData(Qt::UserRole, p_selectID); item->setData(Qt::UserRole, p_selectID);
if (!shortcut.isNull()) {
m_shortcuts.insert(shortcut, item);
}
m_list->insertItem(m_list->count() - 1, item); m_list->insertItem(m_list->count() - 1, item);
m_list->setCurrentRow(0); m_list->setCurrentRow(0);
@ -92,7 +120,8 @@ void SelectDialog::keyPressEvent(QKeyEvent *p_event)
// On Mac OS X, it is `Command+O` to activate an item, instead of Return. // On Mac OS X, it is `Command+O` to activate an item, instead of Return.
#if defined(Q_OS_MACOS) || defined(Q_OS_MAC) #if defined(Q_OS_MACOS) || defined(Q_OS_MAC)
int key = p_event->key(); {
const int key = p_event->key();
if (key == Qt::Key_Return || key == Qt::Key_Enter) { if (key == Qt::Key_Return || key == Qt::Key_Enter) {
p_event->accept(); p_event->accept();
if (auto item = m_list->currentItem()) { if (auto item = m_list->currentItem()) {
@ -101,7 +130,29 @@ void SelectDialog::keyPressEvent(QKeyEvent *p_event)
return; return;
} }
}
#endif #endif
QDialog::keyPressEvent(p_event); QDialog::keyPressEvent(p_event);
} }
bool SelectDialog::eventFilter(QObject *p_watched, QEvent *p_event)
{
if (p_watched == m_list && p_event->type() == QEvent::KeyPress) {
auto keyEve = static_cast<QKeyEvent *>(p_event);
// Handle shortcuts.
if (keyEve->modifiers() == Qt::NoModifier) {
auto keych = Utils::keyToChar(keyEve->key(), true);
if (keych.isLetter()) {
auto it = m_shortcuts.find(keych);
if (it != m_shortcuts.end()) {
selectionChosen(it.value());
}
return true;
}
}
}
return QDialog::eventFilter(p_watched, p_event);
}

View File

@ -24,6 +24,8 @@ namespace vnotex
int getSelection() const; int getSelection() const;
bool eventFilter(QObject *p_watched, QEvent *p_event) Q_DECL_OVERRIDE;
protected: protected:
void showEvent(QShowEvent *p_event) Q_DECL_OVERRIDE; void showEvent(QShowEvent *p_event) Q_DECL_OVERRIDE;
@ -42,6 +44,16 @@ namespace vnotex
int m_choice = CANCEL_ID; int m_choice = CANCEL_ID;
QListWidget *m_list = nullptr; QListWidget *m_list = nullptr;
QMap<QChar, QListWidgetItem *> m_shortcuts;
QString m_shortcutIconForeground;
QString m_shortcutIconBorder;
QChar m_nextShortcut = QLatin1Char('a');
static const QChar c_cancelShortcut;
}; };
} // ns vnotex } // ns vnotex

View File

@ -98,16 +98,15 @@ void QuickSelector::updateItemList()
const auto &themeMgr = VNoteX::getInst().getThemeMgr(); const auto &themeMgr = VNoteX::getInst().getThemeMgr();
const auto fg = themeMgr.paletteColor(QStringLiteral("widgets#quickselector#item_icon#fg"));
const auto border = themeMgr.paletteColor(QStringLiteral("widgets#quickselector#item_icon#border"));
for (int i = 0; i < m_items.size(); ++i) { for (int i = 0; i < m_items.size(); ++i) {
const auto &item = m_items[i]; const auto &item = m_items[i];
auto listItem = new QListWidgetItem(m_itemList); const auto icon = IconUtils::drawTextIcon(item.m_shortcut, fg, border);
auto icon = IconUtils::drawTextIcon(item.m_shortcut, auto listItem = new QListWidgetItem(icon, item.m_name, m_itemList);
themeMgr.paletteColor(QStringLiteral("widgets#quickselector#item_icon#fg")),
themeMgr.paletteColor(QStringLiteral("widgets#quickselector#item_icon#border")));
listItem->setIcon(icon);
listItem->setText(item.m_name);
listItem->setToolTip(item.m_tip); listItem->setToolTip(item.m_tip);
listItem->setData(Qt::UserRole, i); listItem->setData(Qt::UserRole, i);
} }

View File

@ -187,7 +187,7 @@ bool ViewSplit::eventFilter(QObject *p_object, QEvent *p_event)
} }
} }
return false; return QTabWidget::eventFilter(p_object, p_event);
} }
void ViewSplit::setupTabBar() void ViewSplit::setupTabBar()