summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorNicolas Werner <nicolas.werner@hotmail.de>2021-03-13 23:45:05 +0100
committerNicolas Werner <nicolas.werner@hotmail.de>2021-03-13 23:45:05 +0100
commit7a356f3832c2c401d963cd8a654f62ab56a9288b (patch)
treed34e679a6a9f99e579124c55f5b74674c8c7a655 /src
parentDisable bundled OpenSSL by default, even with hunter (diff)
parentchange allowed mistakes, fix minor style issues, remove old completer functio... (diff)
downloadnheko-7a356f3832c2c401d963cd8a654f62ab56a9288b.tar.xz
Merge branch 'quickswitcher_qml' of git://github.com/Jedi18/nheko into Jedi18-quickswitcher_qml
Diffstat (limited to 'src')
-rw-r--r--src/ChatPage.cpp19
-rw-r--r--src/ChatPage.h3
-rw-r--r--src/CompletionProxyModel.cpp7
-rw-r--r--src/CompletionProxyModel.h42
-rw-r--r--src/MainWindow.cpp6
-rw-r--r--src/QuickSwitcher.cpp129
-rw-r--r--src/QuickSwitcher.h65
-rw-r--r--src/timeline/InputBar.cpp22
-rw-r--r--src/timeline/InputBar.h2
-rw-r--r--src/timeline/TimelineViewManager.cpp42
-rw-r--r--src/timeline/TimelineViewManager.h3
11 files changed, 82 insertions, 258 deletions
diff --git a/src/ChatPage.cpp b/src/ChatPage.cpp

index d7ea4301..7c018aff 100644 --- a/src/ChatPage.cpp +++ b/src/ChatPage.cpp
@@ -23,7 +23,6 @@ #include "MainWindow.h" #include "MatrixClient.h" #include "Olm.h" -#include "QuickSwitcher.h" #include "RoomList.h" #include "SideBarActions.h" #include "Splitter.h" @@ -590,18 +589,6 @@ ChatPage::loadStateFromCache() } void -ChatPage::showQuickSwitcher() -{ - auto dialog = new QuickSwitcher(this); - - connect(dialog, &QuickSwitcher::roomSelected, room_list_, &RoomList::highlightSelectedRoom); - connect( - dialog, &QuickSwitcher::closing, this, []() { MainWindow::instance()->hideOverlay(); }); - - MainWindow::instance()->showTransparentOverlayModal(dialog); -} - -void ChatPage::removeRoom(const QString &room_id) { try { @@ -1456,3 +1443,9 @@ ChatPage::handleMatrixUri(const QUrl &uri) { handleMatrixUri(uri.toString(QUrl::ComponentFormattingOption::FullyEncoded).toUtf8()); } + +void +ChatPage::highlightRoom(const QString &room_id) +{ + room_list_->highlightSelectedRoom(room_id); +} \ No newline at end of file diff --git a/src/ChatPage.h b/src/ChatPage.h
index f2078f45..17a4827f 100644 --- a/src/ChatPage.h +++ b/src/ChatPage.h
@@ -31,7 +31,6 @@ #include "notifications/Manager.h" class OverlayModal; -class QuickSwitcher; class RoomList; class SideBarActions; class Splitter; @@ -72,7 +71,6 @@ public: // Initialize all the components of the UI. void bootstrap(QString userid, QString homeserver, QString token); - void showQuickSwitcher(); QString currentRoom() const { return current_room_; } static ChatPage *instance() { return instance_; } @@ -104,6 +102,7 @@ public slots: void startChat(QString userid); void leaveRoom(const QString &room_id); void createRoom(const mtx::requests::CreateRoom &req); + void highlightRoom(const QString &room_id); void joinRoom(const QString &room); void joinRoomVia(const std::string &room_id, const std::vector<std::string> &via, diff --git a/src/CompletionProxyModel.cpp b/src/CompletionProxyModel.cpp
index 44a14911..a6759978 100644 --- a/src/CompletionProxyModel.cpp +++ b/src/CompletionProxyModel.cpp
@@ -10,8 +10,11 @@ #include "Logging.h" #include "Utils.h" -CompletionProxyModel::CompletionProxyModel(QAbstractItemModel *model, QObject *parent) +CompletionProxyModel::CompletionProxyModel(QAbstractItemModel *model, + int max_mistakes, + QObject *parent) : QAbstractProxyModel(parent) + , maxMistakes_(max_mistakes) { setSourceModel(model); QRegularExpression splitPoints("\\s+|-"); @@ -63,7 +66,7 @@ CompletionProxyModel::invalidate() { auto key = searchString.toUcs4(); beginResetModel(); - mapping = trie_.search(key, 7); + mapping = trie_.search(key, 7, maxMistakes_); endResetModel(); std::string temp; diff --git a/src/CompletionProxyModel.h b/src/CompletionProxyModel.h
index 1b8e18f7..214845b7 100644 --- a/src/CompletionProxyModel.h +++ b/src/CompletionProxyModel.h
@@ -58,19 +58,19 @@ struct trie } std::vector<Value> search(const QVector<Key> &keys, //< TODO(Nico): replace this with a span - size_t limit, - size_t max_distance = 2) const + size_t result_count_limit, + size_t max_edit_distance = 2) const { std::vector<Value> ret; - if (!limit) + if (!result_count_limit) return ret; if (keys.isEmpty()) - return valuesAndSubvalues(limit); + return valuesAndSubvalues(result_count_limit); - auto append = [&ret, limit](std::vector<Value> &&in) { + auto append = [&ret, result_count_limit](std::vector<Value> &&in) { for (auto &&v : in) { - if (ret.size() >= limit) + if (ret.size() >= result_count_limit) return; if (std::find(ret.begin(), ret.end(), v) == ret.end()) { @@ -80,11 +80,12 @@ struct trie }; if (auto e = this->next.find(keys[0]); e != this->next.end()) { - append(e->second.search(keys.mid(1), limit, max_distance)); + append( + e->second.search(keys.mid(1), result_count_limit, max_edit_distance)); } - if (max_distance && ret.size() < limit) { - max_distance -= 1; + if (max_edit_distance && ret.size() < result_count_limit) { + max_edit_distance -= 1; // swap chars case if (keys.size() >= 2) { @@ -99,27 +100,31 @@ struct trie } if (t) { - append(t->search( - keys.mid(2), (limit - ret.size()) * 2, max_distance)); + append(t->search(keys.mid(2), + (result_count_limit - ret.size()) * 2, + max_edit_distance)); } } // delete character case - append(this->search(keys.mid(1), (limit - ret.size()) * 2, max_distance)); + append(this->search( + keys.mid(1), (result_count_limit - ret.size()) * 2, max_edit_distance)); // substitute and insert cases for (const auto &[k, t] : this->next) { - if (k == keys[0] || ret.size() >= limit) + if (k == keys[0] || ret.size() >= result_count_limit) break; // substitute - append(t.search(keys.mid(1), limit - ret.size(), max_distance)); + append(t.search( + keys.mid(1), result_count_limit - ret.size(), max_edit_distance)); - if (ret.size() >= limit) + if (ret.size() >= result_count_limit) break; // insert - append(t.search(keys, limit - ret.size(), max_distance)); + append(t.search( + keys, result_count_limit - ret.size(), max_edit_distance)); } } @@ -132,7 +137,9 @@ class CompletionProxyModel : public QAbstractProxyModel Q_OBJECT public: - CompletionProxyModel(QAbstractItemModel *model, QObject *parent = nullptr); + CompletionProxyModel(QAbstractItemModel *model, + int max_mistakes = 2, + QObject *parent = nullptr); void invalidate(); @@ -160,4 +167,5 @@ private: QString searchString; trie<uint, int> trie_; std::vector<int> mapping; + int maxMistakes_; }; diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp
index c405f853..92f43e03 100644 --- a/src/MainWindow.cpp +++ b/src/MainWindow.cpp
@@ -135,12 +135,6 @@ MainWindow::MainWindow(QWidget *parent) QShortcut *quitShortcut = new QShortcut(QKeySequence::Quit, this); connect(quitShortcut, &QShortcut::activated, this, QApplication::quit); - QShortcut *quickSwitchShortcut = new QShortcut(QKeySequence("Ctrl+K"), this); - connect(quickSwitchShortcut, &QShortcut::activated, this, [this]() { - if (chat_page_->isVisible() && !hasActiveDialogs()) - chat_page_->showQuickSwitcher(); - }); - trayIcon_->setVisible(userSettings_->tray()); if (hasActiveUser()) { diff --git a/src/QuickSwitcher.cpp b/src/QuickSwitcher.cpp deleted file mode 100644
index ad2be23d..00000000 --- a/src/QuickSwitcher.cpp +++ /dev/null
@@ -1,129 +0,0 @@ -// SPDX-FileCopyrightText: 2017 Konstantinos Sideris <siderisk@auth.gr> -// SPDX-FileCopyrightText: 2021 Nheko Contributors -// -// SPDX-License-Identifier: GPL-3.0-or-later - -#include <QCompleter> -#include <QPainter> -#include <QStringListModel> -#include <QStyleOption> -#include <QTimer> -#include <QtConcurrent> - -#include "Cache.h" -#include "QuickSwitcher.h" -#include "popups/SuggestionsPopup.h" - -Q_DECLARE_METATYPE(std::vector<RoomSearchResult>) - -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.setPointSizeF(font.pointSizeF() * 1.5); - - 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::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(); - }); -} - -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(); - } -} diff --git a/src/QuickSwitcher.h b/src/QuickSwitcher.h deleted file mode 100644
index 41c53016..00000000 --- a/src/QuickSwitcher.h +++ /dev/null
@@ -1,65 +0,0 @@ -// SPDX-FileCopyrightText: 2017 Konstantinos Sideris <siderisk@auth.gr> -// SPDX-FileCopyrightText: 2021 Nheko Contributors -// -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -#include <QAbstractItemView> -#include <QKeyEvent> -#include <QVBoxLayout> -#include <QWidget> - -#include "popups/SuggestionsPopup.h" -#include "ui/TextField.h" - -class RoomSearchInput : public TextField -{ - Q_OBJECT -public: - explicit RoomSearchInput(QWidget *parent = nullptr); - -signals: - void selectNextCompletion(); - void selectPreviousCompletion(); - void hiding(); - -protected: - void keyPressEvent(QKeyEvent *event) override; - void hideEvent(QHideEvent *event) override; - bool focusNextPrevChild(bool) override { return false; }; -}; - -class QuickSwitcher : public QWidget -{ - Q_OBJECT - -public: - QuickSwitcher(QWidget *parent = nullptr); - -signals: - void closing(); - void roomSelected(const QString &roomid); - void queryResults(const std::vector<RoomSearchResult> &rooms); - -protected: - void keyPressEvent(QKeyEvent *event) override; - void showEvent(QShowEvent *) override { roomSearch_->setFocus(); } - void paintEvent(QPaintEvent *event) override; - -private: - void reset() - { - emit closing(); - roomSearch_->clear(); - } - - // Current highlighted selection from the completer. - int selection_ = -1; - - QVBoxLayout *topLayout_; - RoomSearchInput *roomSearch_; - - //! Autocomplete popup box with the room suggestions. - SuggestionsPopup popup_; -}; diff --git a/src/timeline/InputBar.cpp b/src/timeline/InputBar.cpp
index 490fccc3..d5a6a1dd 100644 --- a/src/timeline/InputBar.cpp +++ b/src/timeline/InputBar.cpp
@@ -192,28 +192,6 @@ InputBar::nextText() return text(); } -QObject * -InputBar::completerFor(QString completerName) -{ - if (completerName == "user") { - auto userModel = new UsersModel(room->roomId().toStdString()); - auto proxy = new CompletionProxyModel(userModel); - userModel->setParent(proxy); - return proxy; - } else if (completerName == "emoji") { - auto emojiModel = new emoji::EmojiModel(); - auto proxy = new CompletionProxyModel(emojiModel); - emojiModel->setParent(proxy); - return proxy; - } else if (completerName == "room") { - auto roomModel = new RoomsModel(true); - auto proxy = new CompletionProxyModel(roomModel); - roomModel->setParent(proxy); - return proxy; - } - return nullptr; -} - void InputBar::send() { diff --git a/src/timeline/InputBar.h b/src/timeline/InputBar.h
index 5af46b0d..acd9e22c 100644 --- a/src/timeline/InputBar.h +++ b/src/timeline/InputBar.h
@@ -55,8 +55,6 @@ public slots: bool uploading() const { return uploading_; } void message(QString body, MarkdownOverride useMarkdown = MarkdownOverride::NOT_SPECIFIED); - QObject *completerFor(QString completerName); - private slots: void startTyping(); void stopTyping(); diff --git a/src/timeline/TimelineViewManager.cpp b/src/timeline/TimelineViewManager.cpp
index 74427855..3ed1c21c 100644 --- a/src/timeline/TimelineViewManager.cpp +++ b/src/timeline/TimelineViewManager.cpp
@@ -15,13 +15,16 @@ #include "BlurhashProvider.h" #include "ChatPage.h" #include "ColorImageProvider.h" +#include "CompletionProxyModel.h" #include "DelegateChooser.h" #include "DeviceVerificationFlow.h" #include "Logging.h" #include "MainWindow.h" #include "MatrixClient.h" #include "MxcImageProvider.h" +#include "RoomsModel.h" #include "UserSettingsPage.h" +#include "UsersModel.h" #include "dialogs/ImageOverlay.h" #include "emoji/EmojiModel.h" #include "emoji/Provider.h" @@ -334,6 +337,12 @@ TimelineViewManager::setHistoryView(const QString &room_id) } } +void +TimelineViewManager::highlightRoom(const QString &room_id) +{ + ChatPage::instance()->highlightRoom(room_id); +} + QString TimelineViewManager::escapeEmoji(QString str) const { @@ -556,3 +565,36 @@ TimelineViewManager::focusMessageInput() { emit focusInput(); } + +QObject * +TimelineViewManager::completerFor(QString completerName, QString roomId) +{ + if (completerName == "user") { + auto userModel = new UsersModel(roomId.toStdString()); + auto proxy = new CompletionProxyModel(userModel); + userModel->setParent(proxy); + return proxy; + } else if (completerName == "emoji") { + auto emojiModel = new emoji::EmojiModel(); + auto proxy = new CompletionProxyModel(emojiModel); + emojiModel->setParent(proxy); + return proxy; + } else if (completerName == "room") { + auto roomModel = new RoomsModel(false); + auto proxy = new CompletionProxyModel(roomModel, 4); + roomModel->setParent(proxy); + return proxy; + } else if (completerName == "roomAliases") { + auto roomModel = new RoomsModel(true); + auto proxy = new CompletionProxyModel(roomModel); + roomModel->setParent(proxy); + return proxy; + } + return nullptr; +} + +void +TimelineViewManager::focusTimeline() +{ + getWidget()->setFocus(); +} \ No newline at end of file diff --git a/src/timeline/TimelineViewManager.h b/src/timeline/TimelineViewManager.h
index 097fccfc..e3ed4991 100644 --- a/src/timeline/TimelineViewManager.h +++ b/src/timeline/TimelineViewManager.h
@@ -104,6 +104,8 @@ public slots: } void setHistoryView(const QString &room_id); + void highlightRoom(const QString &room_id); + void focusTimeline(); TimelineModel *getHistoryView(const QString &room_id) { auto room = models.find(room_id); @@ -142,6 +144,7 @@ public slots: } void backToRooms() { emit showRoomList(); } + QObject *completerFor(QString completerName, QString roomId = ""); private: #ifdef USE_QUICK_VIEW