Split completion model into header and source

This commit is contained in:
Nicolas Werner 2020-11-24 15:35:56 +01:00
parent 9c8850a46c
commit 7cf66ea4f3
3 changed files with 145 additions and 110 deletions

View File

@ -283,6 +283,7 @@ set(SRC_FILES
src/ColorImageProvider.cpp
src/CommunitiesList.cpp
src/CommunitiesListItem.cpp
src/CompletionProxyModel.cpp
src/DeviceVerificationFlow.cpp
src/EventAccessors.cpp
src/InviteeItem.cpp

View File

@ -0,0 +1,133 @@
#include "CompletionProxyModel.h"
#include <QRegularExpression>
#include "CompletionModelRoles.h"
#include "Logging.h"
#include "Utils.h"
CompletionProxyModel::CompletionProxyModel(QAbstractItemModel *model, QObject *parent)
: QAbstractProxyModel(parent)
{
setSourceModel(model);
QRegularExpression splitPoints("\\s+|-");
for (int i = 0; i < sourceModel()->rowCount(); i++) {
if (i < 7)
mapping.push_back(i);
auto string1 = sourceModel()
->data(sourceModel()->index(i, 0), CompletionModel::SearchRole)
.toString()
.toLower();
trie_.insert(string1.toUcs4(), i);
for (const auto &e : string1.split(splitPoints, Qt::SkipEmptyParts)) {
trie_.insert(e.toUcs4(), i);
}
auto string2 = sourceModel()
->data(sourceModel()->index(i, 0), CompletionModel::SearchRole2)
.toString()
.toLower();
if (!string2.isEmpty()) {
trie_.insert(string2.toUcs4(), i);
for (const auto &e : string2.split(splitPoints, Qt::SkipEmptyParts)) {
trie_.insert(e.toUcs4(), i);
}
}
}
connect(
this,
&CompletionProxyModel::newSearchString,
this,
[this](QString s) {
s.remove(":");
s.remove("@");
searchString = s.toLower();
invalidate();
},
Qt::QueuedConnection);
}
void
CompletionProxyModel::invalidate()
{
auto key = searchString.toUcs4();
beginResetModel();
mapping = trie_.search(key, 7);
endResetModel();
std::string temp;
for (auto v : mapping) {
temp += std::to_string(v) + ", ";
}
nhlog::ui()->debug("mapping: {}", temp);
}
QHash<int, QByteArray>
CompletionProxyModel::roleNames() const
{
return this->sourceModel()->roleNames();
}
int
CompletionProxyModel::rowCount(const QModelIndex &) const
{
return (int)mapping.size();
}
QModelIndex
CompletionProxyModel::mapFromSource(const QModelIndex &sourceIndex) const
{
for (int i = 0; i < (int)mapping.size(); i++) {
if (mapping[i] == sourceIndex.row()) {
return index(i, 0);
}
}
return QModelIndex();
}
QModelIndex
CompletionProxyModel::mapToSource(const QModelIndex &proxyIndex) const
{
auto row = proxyIndex.row();
if (row < 0 || row >= (int)mapping.size())
return QModelIndex();
return sourceModel()->index(mapping[row], 0);
}
QModelIndex
CompletionProxyModel::index(int row, int column, const QModelIndex &) const
{
return createIndex(row, column);
}
QModelIndex
CompletionProxyModel::parent(const QModelIndex &) const
{
return QModelIndex{};
}
int
CompletionProxyModel::columnCount(const QModelIndex &) const
{
return sourceModel()->columnCount();
}
QVariant
CompletionProxyModel::completionAt(int i) const
{
if (i >= 0 && i < rowCount())
return data(index(i, 0), CompletionModel::CompletionRole);
else
return {};
}
void
CompletionProxyModel::setSearchString(QString s)
{
emit newSearchString(s);
}

View File

@ -3,11 +3,6 @@
// Class for showing a limited amount of completions at a time
#include <QAbstractProxyModel>
#include <QRegularExpression>
#include "CompletionModelRoles.h"
#include "Logging.h"
#include "Utils.h"
template<typename Key, typename Value>
struct trie
@ -133,120 +128,26 @@ class CompletionProxyModel : public QAbstractProxyModel
Q_OBJECT
public:
CompletionProxyModel(QAbstractItemModel *model, QObject *parent = nullptr)
: QAbstractProxyModel(parent)
{
setSourceModel(model);
QRegularExpression splitPoints("\\s+|-");
CompletionProxyModel(QAbstractItemModel *model, QObject *parent = nullptr);
for (int i = 0; i < sourceModel()->rowCount(); i++) {
if (i < 7)
mapping.push_back(i);
void invalidate();
auto string1 =
sourceModel()
->data(sourceModel()->index(i, 0), CompletionModel::SearchRole)
.toString()
.toLower();
trie_.insert(string1.toUcs4(), i);
QHash<int, QByteArray> roleNames() const override;
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
int columnCount(const QModelIndex &) const override;
for (const auto &e : string1.split(splitPoints, Qt::SkipEmptyParts)) {
trie_.insert(e.toUcs4(), i);
}
auto string2 =
sourceModel()
->data(sourceModel()->index(i, 0), CompletionModel::SearchRole2)
.toString()
.toLower();
if (!string2.isEmpty()) {
trie_.insert(string2.toUcs4(), i);
for (const auto &e :
string2.split(splitPoints, Qt::SkipEmptyParts)) {
trie_.insert(e.toUcs4(), i);
}
}
}
connect(
this,
&CompletionProxyModel::newSearchString,
this,
[this](QString s) {
s.remove(":");
s.remove("@");
searchString = s.toLower();
invalidate();
},
Qt::QueuedConnection);
}
void invalidate()
{
auto key = searchString.toUcs4();
beginResetModel();
mapping = trie_.search(key, 7);
endResetModel();
std::string temp;
for (auto v : mapping) {
temp += std::to_string(v) + ", ";
}
nhlog::ui()->debug("mapping: {}", temp);
};
QHash<int, QByteArray> roleNames() const override
{
return this->sourceModel()->roleNames();
}
int rowCount(const QModelIndex &parent = QModelIndex()) const override
{
(void)parent;
return (int)mapping.size();
}
QModelIndex mapFromSource(const QModelIndex &sourceIndex) const override
{
for (int i = 0; i < (int)mapping.size(); i++) {
if (mapping[i] == sourceIndex.row()) {
return index(i, 0);
}
}
return QModelIndex();
}
QModelIndex mapToSource(const QModelIndex &proxyIndex) const override
{
auto row = proxyIndex.row();
if (row < 0 || row >= (int)mapping.size())
return QModelIndex();
return sourceModel()->index(mapping[row], 0);
}
QModelIndex mapFromSource(const QModelIndex &sourceIndex) const override;
QModelIndex mapToSource(const QModelIndex &proxyIndex) const override;
QModelIndex index(int row,
int column,
const QModelIndex &parent = QModelIndex()) const override
{
(void)parent;
return createIndex(row, column);
}
QModelIndex parent(const QModelIndex &) const override { return QModelIndex{}; }
int columnCount(const QModelIndex &) const override { return sourceModel()->columnCount(); }
const QModelIndex &parent = QModelIndex()) const override;
QModelIndex parent(const QModelIndex &) const override;
public slots:
QVariant completionAt(int i) const
{
if (i >= 0 && i < rowCount())
return data(index(i, 0), CompletionModel::CompletionRole);
else
return {};
}
QVariant completionAt(int i) const;
void setSearchString(QString s) { emit newSearchString(s); }
void setSearchString(QString s);
signals:
void newSearchString(QString);