change allowed mistakes, fix minor style issues, remove old completer function from inputbar
This commit is contained in:
parent
1f8a3ae1e8
commit
8870455f9d
@ -92,6 +92,7 @@ Popup {
|
|||||||
model: completer
|
model: completer
|
||||||
verticalLayoutDirection: popup.bottomToTop ? ListView.BottomToTop : ListView.TopToBottom
|
verticalLayoutDirection: popup.bottomToTop ? ListView.BottomToTop : ListView.TopToBottom
|
||||||
spacing: rowSpacing
|
spacing: rowSpacing
|
||||||
|
pixelAligned: true
|
||||||
|
|
||||||
delegate: Rectangle {
|
delegate: Rectangle {
|
||||||
color: model.index == popup.currentIndex ? colors.highlight : colors.base
|
color: model.index == popup.currentIndex ? colors.highlight : colors.base
|
||||||
@ -202,6 +203,7 @@ Popup {
|
|||||||
|
|
||||||
Label {
|
Label {
|
||||||
text: model.roomName
|
text: model.roomName
|
||||||
|
font.pixelSize: popup.avatarHeight * 0.5
|
||||||
color: model.index == popup.currentIndex ? colors.highlightedText : colors.text
|
color: model.index == popup.currentIndex ? colors.highlightedText : colors.text
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,8 +2,13 @@ import QtQuick 2.13
|
|||||||
import QtQuick.Layouts 1.13
|
import QtQuick.Layouts 1.13
|
||||||
import QtQuick.Controls 2.13
|
import QtQuick.Controls 2.13
|
||||||
|
|
||||||
TextInput {
|
TextField {
|
||||||
id: input
|
id: input
|
||||||
|
palette: colors
|
||||||
|
|
||||||
|
background: Rectangle {
|
||||||
|
color: colors.base
|
||||||
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: blueBar
|
id: blueBar
|
||||||
|
@ -5,7 +5,7 @@ import im.nheko 1.0
|
|||||||
Popup {
|
Popup {
|
||||||
id: quickSwitcher
|
id: quickSwitcher
|
||||||
|
|
||||||
property int textHeight: 48
|
property int textHeight: 32
|
||||||
property int textMargin: 8
|
property int textMargin: 8
|
||||||
|
|
||||||
x: parent.width / 2 - width / 2
|
x: parent.width / 2 - width / 2
|
||||||
@ -49,9 +49,9 @@ Popup {
|
|||||||
Completer {
|
Completer {
|
||||||
id: completerPopup
|
id: completerPopup
|
||||||
|
|
||||||
x: roomTextInput.x - 5
|
x: roomTextInput.x
|
||||||
y: roomTextInput.y + roomTextInput.height + 5
|
y: roomTextInput.y + roomTextInput.height + textMargin
|
||||||
width: parent.width + 10
|
width: parent.width
|
||||||
completerName: "room"
|
completerName: "room"
|
||||||
bottomToTop: false
|
bottomToTop: false
|
||||||
fullWidth: true
|
fullWidth: true
|
||||||
@ -77,7 +77,6 @@ Popup {
|
|||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
onCompletionSelected: {
|
onCompletionSelected: {
|
||||||
console.log(id)
|
|
||||||
TimelineManager.setHistoryView(id)
|
TimelineManager.setHistoryView(id)
|
||||||
TimelineManager.highlightRoom(id)
|
TimelineManager.highlightRoom(id)
|
||||||
quickSwitcher.close()
|
quickSwitcher.close()
|
||||||
|
@ -6,8 +6,11 @@
|
|||||||
#include "Logging.h"
|
#include "Logging.h"
|
||||||
#include "Utils.h"
|
#include "Utils.h"
|
||||||
|
|
||||||
CompletionProxyModel::CompletionProxyModel(QAbstractItemModel *model, QObject *parent)
|
CompletionProxyModel::CompletionProxyModel(QAbstractItemModel *model,
|
||||||
|
int max_mistakes,
|
||||||
|
QObject *parent)
|
||||||
: QAbstractProxyModel(parent)
|
: QAbstractProxyModel(parent)
|
||||||
|
, maxMistakes_(max_mistakes)
|
||||||
{
|
{
|
||||||
setSourceModel(model);
|
setSourceModel(model);
|
||||||
QRegularExpression splitPoints("\\s+|-");
|
QRegularExpression splitPoints("\\s+|-");
|
||||||
@ -59,7 +62,7 @@ CompletionProxyModel::invalidate()
|
|||||||
{
|
{
|
||||||
auto key = searchString.toUcs4();
|
auto key = searchString.toUcs4();
|
||||||
beginResetModel();
|
beginResetModel();
|
||||||
mapping = trie_.search(key, 7);
|
mapping = trie_.search(key, 7, maxMistakes_);
|
||||||
endResetModel();
|
endResetModel();
|
||||||
|
|
||||||
std::string temp;
|
std::string temp;
|
||||||
|
@ -54,19 +54,19 @@ struct trie
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Value> search(const QVector<Key> &keys, //< TODO(Nico): replace this with a span
|
std::vector<Value> search(const QVector<Key> &keys, //< TODO(Nico): replace this with a span
|
||||||
size_t limit,
|
size_t result_count_limit,
|
||||||
size_t max_distance = 2) const
|
size_t max_edit_distance = 2) const
|
||||||
{
|
{
|
||||||
std::vector<Value> ret;
|
std::vector<Value> ret;
|
||||||
if (!limit)
|
if (!result_count_limit)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
if (keys.isEmpty())
|
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) {
|
for (auto &&v : in) {
|
||||||
if (ret.size() >= limit)
|
if (ret.size() >= result_count_limit)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (std::find(ret.begin(), ret.end(), v) == ret.end()) {
|
if (std::find(ret.begin(), ret.end(), v) == ret.end()) {
|
||||||
@ -76,11 +76,12 @@ struct trie
|
|||||||
};
|
};
|
||||||
|
|
||||||
if (auto e = this->next.find(keys[0]); e != this->next.end()) {
|
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) {
|
if (max_edit_distance && ret.size() < result_count_limit) {
|
||||||
max_distance -= 1;
|
max_edit_distance -= 1;
|
||||||
|
|
||||||
// swap chars case
|
// swap chars case
|
||||||
if (keys.size() >= 2) {
|
if (keys.size() >= 2) {
|
||||||
@ -95,27 +96,31 @@ struct trie
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (t) {
|
if (t) {
|
||||||
append(t->search(
|
append(t->search(keys.mid(2),
|
||||||
keys.mid(2), (limit - ret.size()) * 2, max_distance));
|
(result_count_limit - ret.size()) * 2,
|
||||||
|
max_edit_distance));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// delete character case
|
// 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
|
// substitute and insert cases
|
||||||
for (const auto &[k, t] : this->next) {
|
for (const auto &[k, t] : this->next) {
|
||||||
if (k == keys[0] || ret.size() >= limit)
|
if (k == keys[0] || ret.size() >= result_count_limit)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// substitute
|
// 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;
|
break;
|
||||||
|
|
||||||
// insert
|
// insert
|
||||||
append(t.search(keys, limit - ret.size(), max_distance));
|
append(t.search(
|
||||||
|
keys, result_count_limit - ret.size(), max_edit_distance));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -128,7 +133,9 @@ class CompletionProxyModel : public QAbstractProxyModel
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CompletionProxyModel(QAbstractItemModel *model, QObject *parent = nullptr);
|
CompletionProxyModel(QAbstractItemModel *model,
|
||||||
|
int max_mistakes = 2,
|
||||||
|
QObject *parent = nullptr);
|
||||||
|
|
||||||
void invalidate();
|
void invalidate();
|
||||||
|
|
||||||
@ -156,4 +163,5 @@ private:
|
|||||||
QString searchString;
|
QString searchString;
|
||||||
trie<uint, int> trie_;
|
trie<uint, int> trie_;
|
||||||
std::vector<int> mapping;
|
std::vector<int> mapping;
|
||||||
|
int maxMistakes_;
|
||||||
};
|
};
|
||||||
|
@ -174,28 +174,6 @@ InputBar::nextText()
|
|||||||
return text();
|
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
|
void
|
||||||
InputBar::send()
|
InputBar::send()
|
||||||
{
|
{
|
||||||
|
@ -51,8 +51,6 @@ public slots:
|
|||||||
bool uploading() const { return uploading_; }
|
bool uploading() const { return uploading_; }
|
||||||
void message(QString body, MarkdownOverride useMarkdown = MarkdownOverride::NOT_SPECIFIED);
|
void message(QString body, MarkdownOverride useMarkdown = MarkdownOverride::NOT_SPECIFIED);
|
||||||
|
|
||||||
QObject *completerFor(QString completerName);
|
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void startTyping();
|
void startTyping();
|
||||||
void stopTyping();
|
void stopTyping();
|
||||||
|
@ -577,7 +577,7 @@ TimelineViewManager::completerFor(QString completerName, QString roomId)
|
|||||||
return proxy;
|
return proxy;
|
||||||
} else if (completerName == "room") {
|
} else if (completerName == "room") {
|
||||||
auto roomModel = new RoomsModel(false);
|
auto roomModel = new RoomsModel(false);
|
||||||
auto proxy = new CompletionProxyModel(roomModel);
|
auto proxy = new CompletionProxyModel(roomModel, 4);
|
||||||
roomModel->setParent(proxy);
|
roomModel->setParent(proxy);
|
||||||
return proxy;
|
return proxy;
|
||||||
} else if (completerName == "roomAliases") {
|
} else if (completerName == "roomAliases") {
|
||||||
|
Loading…
Reference in New Issue
Block a user