2017-08-15 21:06:27 +03:00
|
|
|
/*
|
|
|
|
* 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>
|
2018-03-22 10:16:17 +03:00
|
|
|
#include <QPainter>
|
2017-08-15 21:06:27 +03:00
|
|
|
#include <QStringListModel>
|
2018-03-22 10:16:17 +03:00
|
|
|
#include <QStyleOption>
|
2017-08-15 21:06:27 +03:00
|
|
|
#include <QTimer>
|
2018-04-27 01:57:46 +03:00
|
|
|
#include <QtConcurrent>
|
2017-08-15 21:06:27 +03:00
|
|
|
|
|
|
|
#include "QuickSwitcher.h"
|
|
|
|
|
2017-08-20 13:47:22 +03:00
|
|
|
RoomSearchInput::RoomSearchInput(QWidget *parent)
|
|
|
|
: TextField(parent)
|
2018-02-23 23:06:35 +03:00
|
|
|
{}
|
2017-08-15 21:06:27 +03:00
|
|
|
|
2017-08-20 13:47:22 +03:00
|
|
|
void
|
|
|
|
RoomSearchInput::keyPressEvent(QKeyEvent *event)
|
2017-08-15 21:06:27 +03:00
|
|
|
{
|
2017-09-10 12:59:21 +03:00
|
|
|
if (event->key() == Qt::Key_Tab || event->key() == Qt::Key_Down) {
|
|
|
|
emit selectNextCompletion();
|
|
|
|
event->accept();
|
|
|
|
return;
|
|
|
|
} else if (event->key() == Qt::Key_Up) {
|
|
|
|
emit selectPreviousCompletion();
|
|
|
|
event->accept();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
TextField::keyPressEvent(event);
|
2017-08-15 21:06:27 +03:00
|
|
|
}
|
|
|
|
|
2017-08-20 21:13:00 +03:00
|
|
|
void
|
|
|
|
RoomSearchInput::hideEvent(QHideEvent *event)
|
|
|
|
{
|
2017-09-10 12:59:21 +03:00
|
|
|
emit hiding();
|
|
|
|
TextField::hideEvent(event);
|
2017-08-20 21:13:00 +03:00
|
|
|
}
|
|
|
|
|
2018-04-27 01:57:46 +03:00
|
|
|
QuickSwitcher::QuickSwitcher(QSharedPointer<Cache> cache, QWidget *parent)
|
2018-03-22 10:16:17 +03:00
|
|
|
: QWidget(parent)
|
2018-04-27 01:57:46 +03:00
|
|
|
, cache_{cache}
|
2017-08-15 21:06:27 +03:00
|
|
|
{
|
2018-04-27 01:57:46 +03:00
|
|
|
qRegisterMetaType<std::vector<RoomSearchResult>>();
|
2017-09-10 12:59:21 +03:00
|
|
|
setMaximumWidth(450);
|
|
|
|
|
|
|
|
QFont font;
|
|
|
|
font.setPixelSize(20);
|
|
|
|
|
|
|
|
roomSearch_ = new RoomSearchInput(this);
|
|
|
|
roomSearch_->setFont(font);
|
2018-04-27 01:57:46 +03:00
|
|
|
roomSearch_->setPlaceholderText(tr("Search for a room..."));
|
2017-09-10 12:59:21 +03:00
|
|
|
|
|
|
|
topLayout_ = new QVBoxLayout(this);
|
|
|
|
topLayout_->addWidget(roomSearch_);
|
|
|
|
|
2018-04-27 01:57:46 +03:00
|
|
|
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();
|
2017-09-10 12:59:21 +03:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2018-04-27 01:57:46 +03:00
|
|
|
QtConcurrent::run([this, query = query.toLower()]() {
|
|
|
|
try {
|
|
|
|
emit queryResults(cache_->searchRooms(query.toStdString()));
|
|
|
|
} catch (const lmdb::error &e) {
|
|
|
|
qWarning() << "room search failed:" << e.what();
|
|
|
|
}
|
|
|
|
});
|
2017-09-10 12:59:21 +03:00
|
|
|
});
|
|
|
|
|
2018-04-27 01:57:46 +03:00
|
|
|
connect(roomSearch_,
|
|
|
|
&RoomSearchInput::selectNextCompletion,
|
|
|
|
&popup_,
|
|
|
|
&SuggestionsPopup::selectNextSuggestion);
|
|
|
|
connect(roomSearch_,
|
|
|
|
&RoomSearchInput::selectPreviousCompletion,
|
|
|
|
&popup_,
|
|
|
|
&SuggestionsPopup::selectPreviousSuggestion);
|
2018-04-27 14:04:13 +03:00
|
|
|
connect(&popup_, &SuggestionsPopup::itemSelected, this, [this](const QString &room_id) {
|
|
|
|
reset();
|
|
|
|
emit roomSelected(room_id);
|
|
|
|
});
|
2018-04-27 01:57:46 +03:00
|
|
|
connect(roomSearch_, &RoomSearchInput::hiding, this, [this]() { popup_.hide(); });
|
2018-02-20 18:09:11 +03:00
|
|
|
connect(roomSearch_, &QLineEdit::returnPressed, this, [this]() {
|
2018-04-27 14:04:13 +03:00
|
|
|
reset();
|
2018-04-27 01:57:46 +03:00
|
|
|
popup_.selectHoveredSuggestion<RoomItem>();
|
2017-09-10 12:59:21 +03:00
|
|
|
});
|
2017-08-15 21:06:27 +03:00
|
|
|
}
|
|
|
|
|
2017-08-20 13:47:22 +03:00
|
|
|
void
|
2018-03-22 10:16:17 +03:00
|
|
|
QuickSwitcher::paintEvent(QPaintEvent *)
|
2017-08-15 21:06:27 +03:00
|
|
|
{
|
2018-03-22 10:16:17 +03:00
|
|
|
QStyleOption opt;
|
|
|
|
opt.init(this);
|
|
|
|
QPainter p(this);
|
|
|
|
style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
|
2017-08-15 21:06:27 +03:00
|
|
|
}
|
|
|
|
|
2017-08-20 13:47:22 +03:00
|
|
|
void
|
|
|
|
QuickSwitcher::keyPressEvent(QKeyEvent *event)
|
2017-08-15 21:06:27 +03:00
|
|
|
{
|
2017-09-10 12:59:21 +03:00
|
|
|
if (event->key() == Qt::Key_Escape) {
|
|
|
|
event->accept();
|
2018-04-27 14:04:13 +03:00
|
|
|
reset();
|
2017-09-10 12:59:21 +03:00
|
|
|
}
|
2017-08-15 21:06:27 +03:00
|
|
|
}
|