summary refs log tree commit diff
path: root/src/QuickSwitcher.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/QuickSwitcher.cpp')
-rw-r--r--src/QuickSwitcher.cpp139
1 files changed, 139 insertions, 0 deletions
diff --git a/src/QuickSwitcher.cpp b/src/QuickSwitcher.cpp
new file mode 100644

index 00000000..07460efb --- /dev/null +++ b/src/QuickSwitcher.cpp
@@ -0,0 +1,139 @@ +/* + * nheko Copyright (C) 2017 Konstantinos Sideris <siderisk@auth.gr> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <QCompleter> +#include <QPainter> +#include <QStringListModel> +#include <QStyleOption> +#include <QTimer> +#include <QtConcurrent> + +#include "QuickSwitcher.h" +#include "SuggestionsPopup.h" + +RoomSearchInput::RoomSearchInput(QWidget *parent) + : TextField(parent) +{} + +void +RoomSearchInput::keyPressEvent(QKeyEvent *event) +{ + switch (event->key()) { + case Qt::Key_Tab: + case Qt::Key_Down: { + emit selectNextCompletion(); + event->accept(); + break; + } + case Qt::Key_Backtab: + case Qt::Key_Up: { + emit selectPreviousCompletion(); + event->accept(); + break; + } + default: + TextField::keyPressEvent(event); + } +} + +void +RoomSearchInput::hideEvent(QHideEvent *event) +{ + emit hiding(); + TextField::hideEvent(event); +} + +QuickSwitcher::QuickSwitcher(QWidget *parent) + : QWidget(parent) +{ + qRegisterMetaType<std::vector<RoomSearchResult>>(); + setMaximumWidth(450); + + QFont font; + font.setPixelSize(20); + + roomSearch_ = new RoomSearchInput(this); + roomSearch_->setFont(font); + roomSearch_->setPlaceholderText(tr("Search for a room...")); + + topLayout_ = new QVBoxLayout(this); + topLayout_->addWidget(roomSearch_); + + connect(this, + &QuickSwitcher::queryResults, + this, + [this](const std::vector<RoomSearchResult> &rooms) { + auto pos = mapToGlobal(roomSearch_->geometry().bottomLeft()); + + popup_.setFixedWidth(width()); + popup_.addRooms(rooms); + popup_.move(pos.x() - topLayout_->margin(), pos.y() + topLayout_->margin()); + popup_.show(); + }); + + connect(roomSearch_, &QLineEdit::textEdited, this, [this](const QString &query) { + if (query.isEmpty()) { + popup_.hide(); + return; + } + + QtConcurrent::run([this, query = query.toLower()]() { + try { + emit queryResults( + cache::client()->searchRooms(query.toStdString())); + } catch (const lmdb::error &e) { + qWarning() << "room search failed:" << e.what(); + } + }); + }); + + connect(roomSearch_, + &RoomSearchInput::selectNextCompletion, + &popup_, + &SuggestionsPopup::selectNextSuggestion); + connect(roomSearch_, + &RoomSearchInput::selectPreviousCompletion, + &popup_, + &SuggestionsPopup::selectPreviousSuggestion); + connect(&popup_, &SuggestionsPopup::itemSelected, this, [this](const QString &room_id) { + reset(); + emit roomSelected(room_id); + }); + connect(roomSearch_, &RoomSearchInput::hiding, this, [this]() { popup_.hide(); }); + connect(roomSearch_, &QLineEdit::returnPressed, this, [this]() { + reset(); + popup_.selectHoveredSuggestion<RoomItem>(); + }); +} + +void +QuickSwitcher::paintEvent(QPaintEvent *) +{ + QStyleOption opt; + opt.init(this); + QPainter p(this); + style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); +} + +void +QuickSwitcher::keyPressEvent(QKeyEvent *event) +{ + if (event->key() == Qt::Key_Escape) { + event->accept(); + reset(); + } +}