diff --git a/CHANGELOG.md b/CHANGELOG.md index d10e783b..cbfdfca0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ - Minor: When (re-)connecting, visible channels are now joined first. (#5850) - Minor: Added the ability to filter on messages by the author's user ID (example: `author.user_id == "22484632"`). (#5862) - Minor: Improved error messaging of the `/clip` command. (#5879) +- Minor: Added searchable hotkeys to global search and make keybinds searchable in the Hotkeys settings. (#5884) - Minor: Added Linux support for Live Notifications toasts. (#5881, #5971, #5976) - Minor: Messages can now be deleted from the context menu in a channel. (#5956) - Minor: Overlay windows now inherit the global zoom level and can be zoomed independently. (#6016) diff --git a/src/widgets/helper/EditableModelView.cpp b/src/widgets/helper/EditableModelView.cpp index c2d9ee6c..7bed6035 100644 --- a/src/widgets/helper/EditableModelView.cpp +++ b/src/widgets/helper/EditableModelView.cpp @@ -150,6 +150,65 @@ void EditableModelView::addRegexHelpLink() this->addCustomButton(regexHelpLabel); } +bool EditableModelView::filterSearchResults(const QString &query, + std::span columnSelect) +{ + bool searchFoundSomething = false; + auto rowAmount = this->model_->rowCount(); + + // make sure to show the page even if the table is empty, + // but only if we aren't search something + if (rowAmount == 0 && query.isEmpty()) + { + return true; + } + + for (int i = 0; i < rowAmount; i++) + { + bool foundMatch = false; + + for (int j : columnSelect) + { + QModelIndex idx = model_->index(i, j); + QVariant a = model_->data(idx); + if (a.toString().contains(query, Qt::CaseInsensitive)) + { + foundMatch = true; + searchFoundSomething = true; + break; + } + } + + tableView_->setRowHidden(i, !foundMatch); + } + + return searchFoundSomething; +} + +void EditableModelView::filterSearchResultsHotkey( + const QKeySequence &keySequenceQuery) +{ + auto rowAmount = this->model_->rowCount(); + + for (int i = 0; i < rowAmount; i++) + { + QModelIndex idx = model_->index(i, 1); + QVariant a = model_->data(idx); + auto seq = qvariant_cast(a); + + // todo: Make this fuzzy match, right now only exact matches happen + // so ctrl+f won't match ctrl+shift+f shortcuts + if (keySequenceQuery.matches(seq) != QKeySequence::NoMatch) + { + tableView_->showRow(i); + } + else + { + tableView_->hideRow(i); + } + } +} + void EditableModelView::moveRow(int dir) { auto selected = this->getTableView()->selectionModel()->selectedRows(0); diff --git a/src/widgets/helper/EditableModelView.hpp b/src/widgets/helper/EditableModelView.hpp index 37bff144..851394ba 100644 --- a/src/widgets/helper/EditableModelView.hpp +++ b/src/widgets/helper/EditableModelView.hpp @@ -1,8 +1,11 @@ #pragma once #include +#include #include +#include + class QAbstractTableModel; class QTableView; class QHBoxLayout; @@ -25,6 +28,10 @@ public: void addCustomButton(QWidget *widget); void addRegexHelpLink(); + bool filterSearchResults(const QString &query, + std::span columnSelect); + void filterSearchResultsHotkey(const QKeySequence &keySequenceQuery); + private: QTableView *tableView_{}; QAbstractTableModel *model_{}; diff --git a/src/widgets/settingspages/KeyboardSettingsPage.cpp b/src/widgets/settingspages/KeyboardSettingsPage.cpp index 85b899d6..63549c14 100644 --- a/src/widgets/settingspages/KeyboardSettingsPage.cpp +++ b/src/widgets/settingspages/KeyboardSettingsPage.cpp @@ -11,10 +11,13 @@ #include #include +#include #include #include #include +#include + namespace { using namespace chatterino; @@ -51,6 +54,7 @@ KeyboardSettingsPage::KeyboardSettingsPage() auto *model = getApp()->getHotkeys()->createModel(nullptr); EditableModelView *view = layout.emplace(model).getElement(); + this->view_ = view; view->setTitles({"Hotkey name", "Keybinding"}); view->getTableView()->horizontalHeader()->setVisible(true); @@ -73,11 +77,25 @@ KeyboardSettingsPage::KeyboardSettingsPage() } }); - QObject::connect(view->getTableView(), &QTableView::doubleClicked, + QObject::connect(view_->getTableView(), &QTableView::doubleClicked, [view, model](const QModelIndex &clicked) { tableCellClicked(clicked, view, model); }); + auto *keySequenceInput = new QKeySequenceEdit(this); + +#if QT_VERSION >= QT_VERSION_CHECK(6, 4, 0) + keySequenceInput->setClearButtonEnabled(true); +#endif + auto *searchText = new QLabel("Search keybind:", this); + + QObject::connect(keySequenceInput, &QKeySequenceEdit::keySequenceChanged, + [view](const QKeySequence &keySequence) { + view->filterSearchResultsHotkey(keySequence); + }); + view->addCustomButton(searchText); + view->addCustomButton(keySequenceInput); + auto *resetEverything = new QPushButton("Reset to defaults"); QObject::connect(resetEverything, &QPushButton::clicked, [this]() { auto reply = QMessageBox::question( @@ -129,4 +147,11 @@ KeyboardSettingsPage::KeyboardSettingsPage() } } +bool KeyboardSettingsPage::filterElements(const QString &query) +{ + std::array fields{0}; + + return this->view_->filterSearchResults(query, fields); +} + } // namespace chatterino diff --git a/src/widgets/settingspages/KeyboardSettingsPage.hpp b/src/widgets/settingspages/KeyboardSettingsPage.hpp index fcd9eed6..a18c3acd 100644 --- a/src/widgets/settingspages/KeyboardSettingsPage.hpp +++ b/src/widgets/settingspages/KeyboardSettingsPage.hpp @@ -11,6 +11,10 @@ class KeyboardSettingsPage : public SettingsPage { public: KeyboardSettingsPage(); + bool filterElements(const QString &query) override; + +private: + EditableModelView *view_; }; } // namespace chatterino