164 lines
5.2 KiB
C++
164 lines
5.2 KiB
C++
#include "buttonsearch.h"
|
|
#include "ui_buttonsearch.h"
|
|
|
|
#include <QVariant>
|
|
|
|
#include <Log.h>
|
|
|
|
static char getSymbol(uint8_t i) {
|
|
return (i < 10) ? ('0' + i) : ('a' + i-10);
|
|
}
|
|
|
|
static bool startsWith(const std::string& a, const std::string& b) {
|
|
// not very performant but working
|
|
return QString().fromStdString(a).toLower().startsWith(QString().fromStdString(b).toLower());
|
|
}
|
|
|
|
ButtonSearch::ButtonSearch(const Config& config, QWidget *parent) : QDialog(parent), config(config), ui(new Ui::ButtonSearch) {
|
|
ui->setupUi(this);
|
|
|
|
Qt::WindowFlags eFlags = windowFlags();
|
|
setWindowFlags(eFlags | Qt::WindowStaysOnTopHint | Qt::X11BypassWindowManagerHint);
|
|
|
|
esc = new QxtGlobalShortcut(QKeySequence("Esc"));
|
|
QObject::connect(esc, &QxtGlobalShortcut::activated, [this](){ buttonPressed(-1); });
|
|
enter = new QxtGlobalShortcut(QKeySequence("Enter"));
|
|
QObject::connect(enter, &QxtGlobalShortcut::activated, [this](){ buttonPressed(-2); });
|
|
|
|
up = new QxtGlobalShortcut(QKeySequence("Up"));
|
|
QObject::connect(up, &QxtGlobalShortcut::activated, std::bind(&ButtonSearch::selectionUp, this));
|
|
down = new QxtGlobalShortcut(QKeySequence("Down"));
|
|
QObject::connect(down, &QxtGlobalShortcut::activated, std::bind(&ButtonSearch::selectionDown, this));
|
|
|
|
for(uint8_t i = 0; i < NUMCOUNT-10; ++i) {
|
|
nums[i] = new QxtGlobalShortcut(QKeySequence(QString() + getSymbol(i)));
|
|
QObject::connect(nums[i], &QxtGlobalShortcut::activated, [this, i](){ buttonPressed(i); });
|
|
}
|
|
|
|
// numpad numbers
|
|
for(uint8_t i = 0; i < 10; ++i) {
|
|
nums[NUMCOUNT-10 +i] = new QxtGlobalShortcut(QKeySequence(QString("Num+") + getSymbol(i)));
|
|
QObject::connect(nums[NUMCOUNT-10 +i], &QxtGlobalShortcut::activated, [this, i](){ buttonPressed(i); });
|
|
}
|
|
}
|
|
|
|
void ButtonSearch::buttonPressed(int i) {
|
|
if(i == -1) {
|
|
// esc
|
|
Log::info << "esc pressed";
|
|
done(-1);
|
|
} else if(i == -2) {
|
|
// enter
|
|
Log::info << "enter pressed";
|
|
closeSearch();
|
|
} else {
|
|
char sym = getSymbol(i);
|
|
Log::info << "button pressed: " << i << " sym: " << getSymbol(i);
|
|
|
|
ui->searchText->setText(ui->searchText->toPlainText() + sym);
|
|
ui->searchResults->clear();
|
|
|
|
// execute search
|
|
const std::string searchStr = ui->searchText->toPlainText().toStdString();
|
|
for(const auto& row : config.rootConfig.buttons) {
|
|
for(const auto& btn : row) {
|
|
if(startsWith(btn.name, searchStr)) {
|
|
QListWidgetItem* item = new QListWidgetItem(QString::fromStdString(btn.name));
|
|
item->setData(Qt::UserRole, QVariant(btn.id));
|
|
ui->searchResults->addItem(item);
|
|
} else if(startsWith(std::to_string(btn.id), searchStr)) {
|
|
QListWidgetItem* item = new QListWidgetItem(QString::fromStdString(btn.name));
|
|
item->setData(Qt::UserRole, QVariant(btn.id));
|
|
ui->searchResults->addItem(item);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void ButtonSearch::closeSearch() {
|
|
QItemSelectionModel* selmod = ui->searchResults->selectionModel();
|
|
auto idx = selmod->selectedRows();
|
|
if(idx.isEmpty()) {
|
|
if(ui->searchResults->count() == 1) {
|
|
Log::info << "only one selected";
|
|
QVariant var = ui->searchResults->item(0)->data(Qt::UserRole);
|
|
assert(var.type() == QVariant::Type::UInt);
|
|
done((int) var.toUInt());
|
|
return;
|
|
}
|
|
|
|
done(-1); // nothing selected
|
|
} else {
|
|
QVariant var = idx.at(0).data(Qt::UserRole);
|
|
assert(var.type() == QVariant::Type::UInt);
|
|
done((int) var.toUInt());
|
|
}
|
|
}
|
|
|
|
void ButtonSearch::selectionDown() {
|
|
Log::info << "down";
|
|
|
|
if(ui->searchResults->count() == 0) {
|
|
Log::warn << "empty search results";
|
|
return; // avoid empty list
|
|
}
|
|
|
|
QItemSelectionModel* selmod = ui->searchResults->selectionModel();
|
|
QAbstractItemModel* itemmod = ui->searchResults->model();
|
|
auto idx = selmod->selectedRows();
|
|
if(idx.isEmpty()) {
|
|
// none selected - select first
|
|
Log::debug << "select first";
|
|
selmod->setCurrentIndex(itemmod->index(0, 0), QItemSelectionModel::SelectionFlag::ClearAndSelect);
|
|
} else {
|
|
// select next
|
|
int selectedRow = idx.at(0).row();
|
|
Log::debug << "idx: " << selectedRow;
|
|
if(ui->searchResults->count() > selectedRow+1) {
|
|
selmod->setCurrentIndex(itemmod->index(selectedRow+1, 0), QItemSelectionModel::SelectionFlag::ClearAndSelect);
|
|
} else {
|
|
// wrap around
|
|
selmod->setCurrentIndex(itemmod->index(0, 0), QItemSelectionModel::SelectionFlag::ClearAndSelect);
|
|
}
|
|
}
|
|
}
|
|
|
|
void ButtonSearch::selectionUp() {
|
|
Log::info << "up";
|
|
|
|
if(ui->searchResults->count() == 0) {
|
|
Log::warn << "empty search results";
|
|
return; // avoid empty list
|
|
}
|
|
|
|
QItemSelectionModel* selmod = ui->searchResults->selectionModel();
|
|
QAbstractItemModel* itemmod = ui->searchResults->model();
|
|
auto idx = selmod->selectedRows();
|
|
if(idx.isEmpty()) {
|
|
// none selected - select last
|
|
Log::debug << "select last";
|
|
selmod->setCurrentIndex(itemmod->index(itemmod->rowCount()-1, 0), QItemSelectionModel::SelectionFlag::ClearAndSelect);
|
|
} else {
|
|
// select next
|
|
int selectedRow = idx.at(0).row();
|
|
Log::debug << "idx: " << selectedRow;
|
|
if(selectedRow-1 >= 0) {
|
|
selmod->setCurrentIndex(itemmod->index(selectedRow-1, 0), QItemSelectionModel::SelectionFlag::ClearAndSelect);
|
|
} else {
|
|
// wrap around
|
|
selmod->setCurrentIndex(itemmod->index(itemmod->rowCount()-1, 0), QItemSelectionModel::SelectionFlag::ClearAndSelect);
|
|
}
|
|
}
|
|
}
|
|
|
|
ButtonSearch::~ButtonSearch() {
|
|
delete ui;
|
|
|
|
delete esc;
|
|
delete enter;
|
|
for(uint8_t i = 0; i < NUMCOUNT; ++i) {
|
|
delete nums[i];
|
|
}
|
|
}
|