mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-06-11 08:34:52 -07:00
implement search bar in shortcuts menu (#5285)
* implement search bar in shortcuts menu * remove unneeded imports * use expandAll
This commit is contained in:
parent
a0e5871c6e
commit
5bdbd51fa8
5 changed files with 197 additions and 75 deletions
|
|
@ -126,6 +126,7 @@ set(cockatrice_SOURCES
|
||||||
src/settings/settings_manager.cpp
|
src/settings/settings_manager.cpp
|
||||||
src/settings/cache_settings.cpp
|
src/settings/cache_settings.cpp
|
||||||
src/settings/shortcuts_settings.cpp
|
src/settings/shortcuts_settings.cpp
|
||||||
|
src/settings/shortcut_treeview.cpp
|
||||||
src/client/sound_engine.cpp
|
src/client/sound_engine.cpp
|
||||||
src/client/network/spoiler_background_updater.cpp
|
src/client/network/spoiler_background_updater.cpp
|
||||||
src/game/zones/stack_zone.cpp
|
src/game/zones/stack_zone.cpp
|
||||||
|
|
|
||||||
|
|
@ -6,10 +6,12 @@
|
||||||
#include "../client/sound_engine.h"
|
#include "../client/sound_engine.h"
|
||||||
#include "../client/ui/picture_loader.h"
|
#include "../client/ui/picture_loader.h"
|
||||||
#include "../client/ui/theme_manager.h"
|
#include "../client/ui/theme_manager.h"
|
||||||
|
#include "../deck/custom_line_edit.h"
|
||||||
#include "../game/cards/card_database.h"
|
#include "../game/cards/card_database.h"
|
||||||
#include "../game/cards/card_database_manager.h"
|
#include "../game/cards/card_database_manager.h"
|
||||||
#include "../main.h"
|
#include "../main.h"
|
||||||
#include "../settings/cache_settings.h"
|
#include "../settings/cache_settings.h"
|
||||||
|
#include "../settings/shortcut_treeview.h"
|
||||||
#include "../utility/sequence_edit.h"
|
#include "../utility/sequence_edit.h"
|
||||||
|
|
||||||
#include <QAction>
|
#include <QAction>
|
||||||
|
|
@ -37,8 +39,6 @@
|
||||||
#include <QStackedWidget>
|
#include <QStackedWidget>
|
||||||
#include <QToolBar>
|
#include <QToolBar>
|
||||||
#include <QTranslator>
|
#include <QTranslator>
|
||||||
#include <QTreeWidget>
|
|
||||||
#include <QTreeWidgetItem>
|
|
||||||
|
|
||||||
#define WIKI_CUSTOM_PIC_URL "https://github.com/Cockatrice/Cockatrice/wiki/Custom-Picture-Download-URLs"
|
#define WIKI_CUSTOM_PIC_URL "https://github.com/Cockatrice/Cockatrice/wiki/Custom-Picture-Download-URLs"
|
||||||
#define WIKI_CUSTOM_SHORTCUTS "https://github.com/Cockatrice/Cockatrice/wiki/Custom-Keyboard-Shortcuts"
|
#define WIKI_CUSTOM_SHORTCUTS "https://github.com/Cockatrice/Cockatrice/wiki/Custom-Keyboard-Shortcuts"
|
||||||
|
|
@ -1257,13 +1257,24 @@ void SoundSettingsPage::retranslateUi()
|
||||||
|
|
||||||
ShortcutSettingsPage::ShortcutSettingsPage()
|
ShortcutSettingsPage::ShortcutSettingsPage()
|
||||||
{
|
{
|
||||||
|
// search bar
|
||||||
|
searchEdit = new SearchLineEdit;
|
||||||
|
searchEdit->setObjectName("searchEdit");
|
||||||
|
searchEdit->setPlaceholderText(tr("Search by shortcut name"));
|
||||||
|
searchEdit->setClearButtonEnabled(true);
|
||||||
|
|
||||||
|
setFocusProxy(searchEdit);
|
||||||
|
setFocusPolicy(Qt::ClickFocus);
|
||||||
|
|
||||||
// table
|
// table
|
||||||
shortcutsTable = new QTreeWidget();
|
shortcutsTable = new ShortcutTreeView(this);
|
||||||
shortcutsTable->setColumnCount(2);
|
|
||||||
shortcutsTable->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
shortcutsTable->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||||
shortcutsTable->setUniformRowHeights(true);
|
shortcutsTable->setEditTriggers(QAbstractItemView::NoEditTriggers);
|
||||||
shortcutsTable->setAlternatingRowColors(true);
|
shortcutsTable->setColumnWidth(0, width() / 3 * 2);
|
||||||
shortcutsTable->header()->resizeSection(0, shortcutsTable->width() / 3 * 2);
|
searchEdit->setTreeView(shortcutsTable);
|
||||||
|
|
||||||
|
connect(searchEdit, &SearchLineEdit::textChanged, shortcutsTable, &ShortcutTreeView::updateSearchString);
|
||||||
|
|
||||||
// edit widget
|
// edit widget
|
||||||
currentActionGroupLabel = new QLabel(this);
|
currentActionGroupLabel = new QLabel(this);
|
||||||
|
|
@ -1303,6 +1314,7 @@ ShortcutSettingsPage::ShortcutSettingsPage()
|
||||||
_buttonsLayout->addWidget(btnClearAll);
|
_buttonsLayout->addWidget(btnClearAll);
|
||||||
|
|
||||||
auto *_mainLayout = new QVBoxLayout;
|
auto *_mainLayout = new QVBoxLayout;
|
||||||
|
_mainLayout->addWidget(searchEdit);
|
||||||
_mainLayout->addWidget(shortcutsTable);
|
_mainLayout->addWidget(shortcutsTable);
|
||||||
_mainLayout->addWidget(editShortcutGroupBox);
|
_mainLayout->addWidget(editShortcutGroupBox);
|
||||||
_mainLayout->addLayout(_buttonsLayout);
|
_mainLayout->addLayout(_buttonsLayout);
|
||||||
|
|
@ -1311,21 +1323,17 @@ ShortcutSettingsPage::ShortcutSettingsPage()
|
||||||
|
|
||||||
connect(btnResetAll, SIGNAL(clicked()), this, SLOT(resetShortcuts()));
|
connect(btnResetAll, SIGNAL(clicked()), this, SLOT(resetShortcuts()));
|
||||||
connect(btnClearAll, SIGNAL(clicked()), this, SLOT(clearShortcuts()));
|
connect(btnClearAll, SIGNAL(clicked()), this, SLOT(clearShortcuts()));
|
||||||
connect(shortcutsTable, SIGNAL(currentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)), this,
|
|
||||||
SLOT(currentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)));
|
|
||||||
connect(&SettingsCache::instance().shortcuts(), SIGNAL(shortCutChanged()), this, SLOT(refreshShortcuts()));
|
|
||||||
|
|
||||||
createShortcuts();
|
connect(shortcutsTable, &ShortcutTreeView::currentItemChanged, this, &ShortcutSettingsPage::currentItemChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShortcutSettingsPage::currentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem * /*previous */)
|
void ShortcutSettingsPage::currentItemChanged(const QString &key)
|
||||||
{
|
{
|
||||||
if (current == nullptr) {
|
if (key.isEmpty()) {
|
||||||
currentActionGroupName->setText("");
|
currentActionGroupName->setText("");
|
||||||
currentActionName->setText("");
|
currentActionName->setText("");
|
||||||
editTextBox->setShortcutName("");
|
editTextBox->setShortcutName("");
|
||||||
} else {
|
} else {
|
||||||
QString key = current->data(2, Qt::DisplayRole).toString();
|
|
||||||
QString group = SettingsCache::instance().shortcuts().getShortcut(key).getGroupName();
|
QString group = SettingsCache::instance().shortcuts().getShortcut(key).getGroupName();
|
||||||
QString action = SettingsCache::instance().shortcuts().getShortcut(key).getName();
|
QString action = SettingsCache::instance().shortcuts().getShortcut(key).getName();
|
||||||
currentActionGroupName->setText(group);
|
currentActionGroupName->setText(group);
|
||||||
|
|
@ -1342,59 +1350,6 @@ void ShortcutSettingsPage::resetShortcuts()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShortcutSettingsPage::createShortcuts()
|
|
||||||
{
|
|
||||||
QHash<QString, QTreeWidgetItem *> parentItems;
|
|
||||||
QTreeWidgetItem *curParent = nullptr;
|
|
||||||
for (const auto &key : SettingsCache::instance().shortcuts().getAllShortcutKeys()) {
|
|
||||||
QString name = SettingsCache::instance().shortcuts().getShortcut(key).getName();
|
|
||||||
QString group = SettingsCache::instance().shortcuts().getShortcut(key).getGroupName();
|
|
||||||
QString shortcut = SettingsCache::instance().shortcuts().getShortcutString(key);
|
|
||||||
|
|
||||||
if (parentItems.contains(group)) {
|
|
||||||
curParent = parentItems.value(group);
|
|
||||||
} else {
|
|
||||||
curParent = new QTreeWidgetItem((QTreeWidget *)nullptr, QStringList({group, "", ""}));
|
|
||||||
static QFont font = curParent->font(0);
|
|
||||||
font.setBold(true);
|
|
||||||
curParent->setFont(0, font);
|
|
||||||
parentItems.insert(group, curParent);
|
|
||||||
}
|
|
||||||
|
|
||||||
new QTreeWidgetItem(curParent, QStringList({name, shortcut, key}));
|
|
||||||
}
|
|
||||||
shortcutsTable->clear();
|
|
||||||
shortcutsTable->insertTopLevelItems(0, parentItems.values());
|
|
||||||
shortcutsTable->setCurrentItem(nullptr);
|
|
||||||
shortcutsTable->expandAll();
|
|
||||||
shortcutsTable->sortItems(0, Qt::AscendingOrder);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ShortcutSettingsPage::refreshShortcuts()
|
|
||||||
{
|
|
||||||
QTreeWidgetItem *curParent = nullptr;
|
|
||||||
QTreeWidgetItem *curChild = nullptr;
|
|
||||||
for (int i = 0; i < shortcutsTable->topLevelItemCount(); ++i) {
|
|
||||||
curParent = shortcutsTable->topLevelItem(i);
|
|
||||||
for (int j = 0; j < curParent->childCount(); ++j) {
|
|
||||||
curChild = curParent->child(j);
|
|
||||||
QString key = curChild->data(2, Qt::DisplayRole).toString();
|
|
||||||
QString name = SettingsCache::instance().shortcuts().getShortcut(key).getName();
|
|
||||||
QString shortcut = SettingsCache::instance().shortcuts().getShortcutString(key);
|
|
||||||
curChild->setText(0, name);
|
|
||||||
curChild->setText(1, shortcut);
|
|
||||||
|
|
||||||
if (j == 0) {
|
|
||||||
// the first child also updates the parent's group name
|
|
||||||
QString group = SettingsCache::instance().shortcuts().getShortcut(key).getGroupName();
|
|
||||||
curParent->setText(0, group);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
shortcutsTable->sortItems(0, Qt::AscendingOrder);
|
|
||||||
currentItemChanged(shortcutsTable->currentItem(), nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ShortcutSettingsPage::clearShortcuts()
|
void ShortcutSettingsPage::clearShortcuts()
|
||||||
{
|
{
|
||||||
if (QMessageBox::question(this, tr("Clear all default shortcuts"),
|
if (QMessageBox::question(this, tr("Clear all default shortcuts"),
|
||||||
|
|
@ -1405,8 +1360,7 @@ void ShortcutSettingsPage::clearShortcuts()
|
||||||
|
|
||||||
void ShortcutSettingsPage::retranslateUi()
|
void ShortcutSettingsPage::retranslateUi()
|
||||||
{
|
{
|
||||||
shortcutsTable->setHeaderLabels(QStringList() << tr("Action") << tr("Shortcut"));
|
shortcutsTable->retranslateUi();
|
||||||
refreshShortcuts();
|
|
||||||
|
|
||||||
currentActionGroupLabel->setText(tr("Section:"));
|
currentActionGroupLabel->setText(tr("Section:"));
|
||||||
currentActionLabel->setText(tr("Action:"));
|
currentActionLabel->setText(tr("Action:"));
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,10 @@
|
||||||
#include <QPushButton>
|
#include <QPushButton>
|
||||||
#include <QSpinBox>
|
#include <QSpinBox>
|
||||||
|
|
||||||
|
class ShortcutTreeView;
|
||||||
|
class SearchLineEdit;
|
||||||
|
class QTreeView;
|
||||||
|
class QStandardItemModel;
|
||||||
class CardDatabase;
|
class CardDatabase;
|
||||||
class QCloseEvent;
|
class QCloseEvent;
|
||||||
class QGridLayout;
|
class QGridLayout;
|
||||||
|
|
@ -21,8 +25,6 @@ class QListWidgetItem;
|
||||||
class QRadioButton;
|
class QRadioButton;
|
||||||
class QSlider;
|
class QSlider;
|
||||||
class QStackedWidget;
|
class QStackedWidget;
|
||||||
class QTreeWidget;
|
|
||||||
class QTreeWidgetItem;
|
|
||||||
class QVBoxLayout;
|
class QVBoxLayout;
|
||||||
class SequenceEdit;
|
class SequenceEdit;
|
||||||
|
|
||||||
|
|
@ -268,7 +270,8 @@ public:
|
||||||
void retranslateUi() override;
|
void retranslateUi() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QTreeWidget *shortcutsTable;
|
SearchLineEdit *searchEdit;
|
||||||
|
ShortcutTreeView *shortcutsTable;
|
||||||
QVBoxLayout *mainLayout;
|
QVBoxLayout *mainLayout;
|
||||||
QHBoxLayout *buttonsLayout;
|
QHBoxLayout *buttonsLayout;
|
||||||
QGroupBox *editShortcutGroupBox;
|
QGroupBox *editShortcutGroupBox;
|
||||||
|
|
@ -285,10 +288,8 @@ private:
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void resetShortcuts();
|
void resetShortcuts();
|
||||||
void refreshShortcuts();
|
|
||||||
void createShortcuts();
|
|
||||||
void clearShortcuts();
|
void clearShortcuts();
|
||||||
void currentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous);
|
void currentItemChanged(const QString &key);
|
||||||
};
|
};
|
||||||
|
|
||||||
class DlgSettings : public QDialog
|
class DlgSettings : public QDialog
|
||||||
|
|
|
||||||
132
cockatrice/src/settings/shortcut_treeview.cpp
Normal file
132
cockatrice/src/settings/shortcut_treeview.cpp
Normal file
|
|
@ -0,0 +1,132 @@
|
||||||
|
#include "shortcut_treeview.h"
|
||||||
|
|
||||||
|
#include "cache_settings.h"
|
||||||
|
#include "shortcuts_settings.h"
|
||||||
|
|
||||||
|
#include <QHeaderView>
|
||||||
|
#include <QSortFilterProxyModel>
|
||||||
|
|
||||||
|
ShortcutTreeView::ShortcutTreeView(QWidget *parent) : QTreeView(parent)
|
||||||
|
{
|
||||||
|
// model
|
||||||
|
shortcutsModel = new QStandardItemModel(this);
|
||||||
|
shortcutsModel->setColumnCount(3);
|
||||||
|
populateShortcutsModel();
|
||||||
|
|
||||||
|
// filter proxy
|
||||||
|
proxyModel = new QSortFilterProxyModel(this);
|
||||||
|
proxyModel->setRecursiveFilteringEnabled(true);
|
||||||
|
proxyModel->setSourceModel(shortcutsModel);
|
||||||
|
proxyModel->setDynamicSortFilter(true);
|
||||||
|
proxyModel->setSortCaseSensitivity(Qt::CaseInsensitive);
|
||||||
|
proxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
|
||||||
|
proxyModel->setFilterKeyColumn(0);
|
||||||
|
|
||||||
|
QTreeView::setModel(proxyModel);
|
||||||
|
|
||||||
|
// treeview
|
||||||
|
hideColumn(2);
|
||||||
|
|
||||||
|
setUniformRowHeights(true);
|
||||||
|
setAlternatingRowColors(true);
|
||||||
|
|
||||||
|
setSortingEnabled(true);
|
||||||
|
proxyModel->sort(0, Qt::AscendingOrder);
|
||||||
|
|
||||||
|
header()->setSectionResizeMode(QHeaderView::Interactive);
|
||||||
|
header()->setSortIndicator(0, Qt::AscendingOrder);
|
||||||
|
setSelectionMode(SingleSelection);
|
||||||
|
setSelectionBehavior(SelectRows);
|
||||||
|
|
||||||
|
expandAll();
|
||||||
|
|
||||||
|
connect(&SettingsCache::instance().shortcuts(), &ShortcutsSettings::shortCutChanged, this,
|
||||||
|
&ShortcutTreeView::refreshShortcuts);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShortcutTreeView::populateShortcutsModel()
|
||||||
|
{
|
||||||
|
QHash<QString, QStandardItem *> parentItems;
|
||||||
|
QStandardItem *curParent = nullptr;
|
||||||
|
for (const auto &key : SettingsCache::instance().shortcuts().getAllShortcutKeys()) {
|
||||||
|
QString name = SettingsCache::instance().shortcuts().getShortcut(key).getName();
|
||||||
|
QString group = SettingsCache::instance().shortcuts().getShortcut(key).getGroupName();
|
||||||
|
QString shortcut = SettingsCache::instance().shortcuts().getShortcutString(key);
|
||||||
|
|
||||||
|
if (parentItems.contains(group)) {
|
||||||
|
curParent = parentItems.value(group);
|
||||||
|
} else {
|
||||||
|
curParent = new QStandardItem(group);
|
||||||
|
static QFont font = curParent->font();
|
||||||
|
font.setBold(true);
|
||||||
|
curParent->setFont(font);
|
||||||
|
parentItems.insert(group, curParent);
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<QStandardItem *> list = {};
|
||||||
|
list << new QStandardItem(name) << new QStandardItem(shortcut) << new QStandardItem(key);
|
||||||
|
curParent->appendRow(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto &parent : parentItems) {
|
||||||
|
shortcutsModel->appendRow(parent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShortcutTreeView::retranslateUi()
|
||||||
|
{
|
||||||
|
shortcutsModel->setHeaderData(0, Qt::Horizontal, tr("Action"));
|
||||||
|
shortcutsModel->setHeaderData(1, Qt::Horizontal, tr("Shortcut"));
|
||||||
|
refreshShortcuts();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loops over the model and reloads all rows
|
||||||
|
*/
|
||||||
|
static void loopOverModel(QAbstractItemModel *model, const QModelIndex &parent = QModelIndex())
|
||||||
|
{
|
||||||
|
for (int r = 0; r < model->rowCount(parent); ++r) {
|
||||||
|
const auto friendlyNameIndex = model->index(r, 0, parent);
|
||||||
|
|
||||||
|
if (model->hasChildren(friendlyNameIndex)) {
|
||||||
|
const auto childIndex = model->index(0, 2, friendlyNameIndex);
|
||||||
|
const auto key = model->data(childIndex).toString();
|
||||||
|
const auto shortcutGroupName = SettingsCache::instance().shortcuts().getShortcut(key).getGroupName();
|
||||||
|
model->setData(friendlyNameIndex, shortcutGroupName);
|
||||||
|
|
||||||
|
loopOverModel(model, friendlyNameIndex);
|
||||||
|
} else {
|
||||||
|
const auto shortcutSequenceIndex = model->index(r, 1, parent);
|
||||||
|
const auto keyIndex = model->index(r, 2, parent);
|
||||||
|
const auto key = model->data(keyIndex).toString();
|
||||||
|
|
||||||
|
const auto shortcutKey = SettingsCache::instance().shortcuts().getShortcut(key).getName();
|
||||||
|
const auto shortcutSequence = SettingsCache::instance().shortcuts().getShortcutString(key);
|
||||||
|
model->setData(friendlyNameIndex, shortcutKey);
|
||||||
|
model->setData(shortcutSequenceIndex, shortcutSequence);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShortcutTreeView::refreshShortcuts()
|
||||||
|
{
|
||||||
|
loopOverModel(shortcutsModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShortcutTreeView::currentChanged(const QModelIndex ¤t, const QModelIndex & /* previous */)
|
||||||
|
{
|
||||||
|
QTreeView::scrollTo(current, QAbstractItemView::EnsureVisible);
|
||||||
|
if (current.parent().isValid()) {
|
||||||
|
auto shortcutName = model()->data(model()->index(current.row(), 2, current.parent())).toString();
|
||||||
|
emit currentItemChanged(shortcutName);
|
||||||
|
} else {
|
||||||
|
// emit empty string if the selection is a category header
|
||||||
|
emit currentItemChanged("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShortcutTreeView::updateSearchString(const QString &searchString)
|
||||||
|
{
|
||||||
|
proxyModel->setFilterFixedString(searchString);
|
||||||
|
expandAll();
|
||||||
|
}
|
||||||
34
cockatrice/src/settings/shortcut_treeview.h
Normal file
34
cockatrice/src/settings/shortcut_treeview.h
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
#ifndef SHORTCUT_TREEVIEW_H
|
||||||
|
#define SHORTCUT_TREEVIEW_H
|
||||||
|
|
||||||
|
#include <QModelIndex>
|
||||||
|
#include <QStandardItemModel>
|
||||||
|
#include <QTreeView>
|
||||||
|
|
||||||
|
class QSortFilterProxyModel;
|
||||||
|
class ShortcutTreeView : public QTreeView
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit ShortcutTreeView(QWidget *parent);
|
||||||
|
void retranslateUi();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void currentItemChanged(const QString &shortcut);
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void updateSearchString(const QString &searchString);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QStandardItemModel *shortcutsModel;
|
||||||
|
QSortFilterProxyModel *proxyModel;
|
||||||
|
void populateShortcutsModel();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void refreshShortcuts();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void currentChanged(const QModelIndex ¤t, const QModelIndex &previous) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // SHORTCUT_TREEVIEW_H
|
||||||
Loading…
Add table
Add a link
Reference in a new issue