Reimplement normal emoji completion
BUG: 460632
This commit is contained in:
@@ -49,7 +49,7 @@ set_package_properties(Qt${QT_MAJOR_VERSION} PROPERTIES
|
|||||||
TYPE REQUIRED
|
TYPE REQUIRED
|
||||||
PURPOSE "Basic application components"
|
PURPOSE "Basic application components"
|
||||||
)
|
)
|
||||||
find_package(KF5 ${KF5_MIN_VERSION} COMPONENTS Kirigami2 I18n Notifications Config CoreAddons Sonnet)
|
find_package(KF5 ${KF5_MIN_VERSION} COMPONENTS Kirigami2 I18n Notifications Config CoreAddons Sonnet ItemModels)
|
||||||
set_package_properties(KF5 PROPERTIES
|
set_package_properties(KF5 PROPERTIES
|
||||||
TYPE REQUIRED
|
TYPE REQUIRED
|
||||||
PURPOSE "Basic application components"
|
PURPOSE "Basic application components"
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ else()
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
target_include_directories(neochat PRIVATE ${CMAKE_BINARY_DIR})
|
target_include_directories(neochat PRIVATE ${CMAKE_BINARY_DIR})
|
||||||
target_link_libraries(neochat PUBLIC Qt::Core Qt::Quick Qt::Qml Qt::Gui Qt::Multimedia Qt::Network Qt::QuickControls2 KF5::I18n KF5::Kirigami2 KF5::Notifications KF5::ConfigCore KF5::ConfigGui KF5::CoreAddons KF5::SonnetCore Quotient cmark::cmark ${QTKEYCHAIN_LIBRARIES})
|
target_link_libraries(neochat PUBLIC Qt::Core Qt::Quick Qt::Qml Qt::Gui Qt::Multimedia Qt::Network Qt::QuickControls2 KF5::I18n KF5::Kirigami2 KF5::Notifications KF5::ConfigCore KF5::ConfigGui KF5::CoreAddons KF5::SonnetCore KF5::ItemModels Quotient cmark::cmark ${QTKEYCHAIN_LIBRARIES})
|
||||||
if(TARGET QCoro5::Coro)
|
if(TARGET QCoro5::Coro)
|
||||||
target_link_libraries(neochat PUBLIC QCoro5::Coro)
|
target_link_libraries(neochat PUBLIC QCoro5::Coro)
|
||||||
else()
|
else()
|
||||||
|
|||||||
@@ -235,7 +235,7 @@ void ChatDocumentHandler::complete(int index)
|
|||||||
m_room->mentions()->push_back({cursor, alias, 0, 0, alias});
|
m_room->mentions()->push_back({cursor, alias, 0, 0, alias});
|
||||||
m_highlighter->rehighlight();
|
m_highlighter->rehighlight();
|
||||||
} else if (m_completionModel->autoCompletionType() == ChatDocumentHandler::Emoji) {
|
} else if (m_completionModel->autoCompletionType() == ChatDocumentHandler::Emoji) {
|
||||||
auto shortcode = m_completionModel->data(m_completionModel->index(index, 0), CompletionModel::Text).toString();
|
auto shortcode = m_completionModel->data(m_completionModel->index(index, 0), CompletionModel::ReplacedText).toString();
|
||||||
auto text = m_room->chatBoxText();
|
auto text = m_room->chatBoxText();
|
||||||
auto at = text.lastIndexOf(QLatin1Char(':'));
|
auto at = text.lastIndexOf(QLatin1Char(':'));
|
||||||
QTextCursor cursor(document()->textDocument());
|
QTextCursor cursor(document()->textDocument());
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
#include "chatdocumenthandler.h"
|
#include "chatdocumenthandler.h"
|
||||||
#include "completionproxymodel.h"
|
#include "completionproxymodel.h"
|
||||||
#include "customemojimodel.h"
|
#include "customemojimodel.h"
|
||||||
|
#include "emojimodel.h"
|
||||||
#include "neochatroom.h"
|
#include "neochatroom.h"
|
||||||
#include "roomlistmodel.h"
|
#include "roomlistmodel.h"
|
||||||
#include "userlistmodel.h"
|
#include "userlistmodel.h"
|
||||||
@@ -16,11 +17,14 @@ CompletionModel::CompletionModel(QObject *parent)
|
|||||||
: QAbstractListModel(parent)
|
: QAbstractListModel(parent)
|
||||||
, m_filterModel(new CompletionProxyModel())
|
, m_filterModel(new CompletionProxyModel())
|
||||||
, m_userListModel(new UserListModel(this))
|
, m_userListModel(new UserListModel(this))
|
||||||
|
, m_emojiModel(new KConcatenateRowsProxyModel(this))
|
||||||
{
|
{
|
||||||
connect(this, &CompletionModel::textChanged, this, &CompletionModel::updateCompletion);
|
connect(this, &CompletionModel::textChanged, this, &CompletionModel::updateCompletion);
|
||||||
connect(this, &CompletionModel::roomChanged, this, [this]() {
|
connect(this, &CompletionModel::roomChanged, this, [this]() {
|
||||||
m_userListModel->setRoom(m_room);
|
m_userListModel->setRoom(m_room);
|
||||||
});
|
});
|
||||||
|
m_emojiModel->addSourceModel(&CustomEmojiModel::instance());
|
||||||
|
m_emojiModel->addSourceModel(&EmojiModel::instance());
|
||||||
}
|
}
|
||||||
|
|
||||||
QString CompletionModel::text() const
|
QString CompletionModel::text() const
|
||||||
@@ -90,11 +94,14 @@ QVariant CompletionModel::data(const QModelIndex &index, int role) const
|
|||||||
}
|
}
|
||||||
if (m_autoCompletionType == ChatDocumentHandler::Emoji) {
|
if (m_autoCompletionType == ChatDocumentHandler::Emoji) {
|
||||||
if (role == Text) {
|
if (role == Text) {
|
||||||
return m_filterModel->data(filterIndex, CustomEmojiModel::Name);
|
return m_filterModel->data(filterIndex, CustomEmojiModel::DisplayRole);
|
||||||
}
|
}
|
||||||
if (role == Icon) {
|
if (role == Icon) {
|
||||||
return m_filterModel->data(filterIndex, CustomEmojiModel::MxcUrl);
|
return m_filterModel->data(filterIndex, CustomEmojiModel::MxcUrl);
|
||||||
}
|
}
|
||||||
|
if (role == ReplacedText) {
|
||||||
|
return m_filterModel->data(filterIndex, CustomEmojiModel::ReplacedTextRole);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
@@ -140,7 +147,7 @@ void CompletionModel::updateCompletion()
|
|||||||
&& (m_fullText.indexOf(QLatin1Char(':'), 1) == -1
|
&& (m_fullText.indexOf(QLatin1Char(':'), 1) == -1
|
||||||
|| (m_fullText.indexOf(QLatin1Char(' ')) != -1 && m_fullText.indexOf(QLatin1Char(':'), 1) > m_fullText.indexOf(QLatin1Char(' '), 1)))) {
|
|| (m_fullText.indexOf(QLatin1Char(' ')) != -1 && m_fullText.indexOf(QLatin1Char(':'), 1) > m_fullText.indexOf(QLatin1Char(' '), 1)))) {
|
||||||
m_autoCompletionType = ChatDocumentHandler::Emoji;
|
m_autoCompletionType = ChatDocumentHandler::Emoji;
|
||||||
m_filterModel->setSourceModel(&CustomEmojiModel::instance());
|
m_filterModel->setSourceModel(m_emojiModel);
|
||||||
m_filterModel->setFilterRole(CustomEmojiModel::Name);
|
m_filterModel->setFilterRole(CustomEmojiModel::Name);
|
||||||
m_filterModel->setSecondaryFilterRole(-1);
|
m_filterModel->setSecondaryFilterRole(-1);
|
||||||
m_filterModel->setFullText(m_fullText);
|
m_filterModel->setFullText(m_fullText);
|
||||||
|
|||||||
@@ -5,6 +5,8 @@
|
|||||||
|
|
||||||
#include <QSortFilterProxyModel>
|
#include <QSortFilterProxyModel>
|
||||||
|
|
||||||
|
#include <KConcatenateRowsProxyModel>
|
||||||
|
|
||||||
#include "chatdocumenthandler.h"
|
#include "chatdocumenthandler.h"
|
||||||
|
|
||||||
class CompletionProxyModel;
|
class CompletionProxyModel;
|
||||||
@@ -64,4 +66,5 @@ private:
|
|||||||
|
|
||||||
UserListModel *m_userListModel;
|
UserListModel *m_userListModel;
|
||||||
RoomListModel *m_roomListModel;
|
RoomListModel *m_roomListModel;
|
||||||
|
KConcatenateRowsProxyModel *m_emojiModel;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -134,6 +134,8 @@ QVariant CustomEmojiModel::data(const QModelIndex &idx, int role) const
|
|||||||
case Roles::ModelData:
|
case Roles::ModelData:
|
||||||
return QVariant::fromValue(Emoji(QStringLiteral("image://mxc/") + data.url.mid(6), data.name, true));
|
return QVariant::fromValue(Emoji(QStringLiteral("image://mxc/") + data.url.mid(6), data.name, true));
|
||||||
case Roles::Name:
|
case Roles::Name:
|
||||||
|
case Roles::DisplayRole:
|
||||||
|
case Roles::ReplacedTextRole:
|
||||||
return data.name;
|
return data.name;
|
||||||
case Roles::ImageURL:
|
case Roles::ImageURL:
|
||||||
return QUrl(QStringLiteral("image://mxc/") + data.url.mid(6));
|
return QUrl(QStringLiteral("image://mxc/") + data.url.mid(6));
|
||||||
|
|||||||
@@ -19,10 +19,12 @@ class CustomEmojiModel : public QAbstractListModel
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
enum Roles {
|
enum Roles {
|
||||||
Name,
|
Name = Qt::DisplayRole,
|
||||||
ImageURL,
|
ImageURL,
|
||||||
ModelData, // for emulating the regular emoji model's usage, otherwise the UI code would get too complicated
|
ModelData, // for emulating the regular emoji model's usage, otherwise the UI code would get too complicated
|
||||||
MxcUrl,
|
MxcUrl = 50,
|
||||||
|
DisplayRole = 51,
|
||||||
|
ReplacedTextRole = 52,
|
||||||
};
|
};
|
||||||
Q_ENUM(Roles);
|
Q_ENUM(Roles);
|
||||||
|
|
||||||
|
|||||||
@@ -39,10 +39,15 @@ QVariant EmojiModel::data(const QModelIndex &index, int role) const
|
|||||||
}
|
}
|
||||||
auto emoji = category[row].value<Emoji>();
|
auto emoji = category[row].value<Emoji>();
|
||||||
switch (role) {
|
switch (role) {
|
||||||
case TextRole:
|
case ShortNameRole:
|
||||||
return emoji.shortName;
|
return QStringLiteral(":%1:").arg(emoji.shortName);
|
||||||
case UnicodeRole:
|
case UnicodeRole:
|
||||||
|
case ReplacedTextRole:
|
||||||
return emoji.unicode;
|
return emoji.unicode;
|
||||||
|
case InvalidRole:
|
||||||
|
return QStringLiteral("invalid");
|
||||||
|
case DisplayRole:
|
||||||
|
return QStringLiteral("%2 :%1:").arg(emoji.shortName, emoji.unicode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return {};
|
return {};
|
||||||
@@ -50,7 +55,7 @@ QVariant EmojiModel::data(const QModelIndex &index, int role) const
|
|||||||
|
|
||||||
QHash<int, QByteArray> EmojiModel::roleNames() const
|
QHash<int, QByteArray> EmojiModel::roleNames() const
|
||||||
{
|
{
|
||||||
return {{TextRole, "text"}, {UnicodeRole, "unicode"}};
|
return {{ShortNameRole, "shortName"}, {UnicodeRole, "unicode"}};
|
||||||
}
|
}
|
||||||
|
|
||||||
QMultiHash<QString, QVariant> EmojiModel::_tones = {
|
QMultiHash<QString, QVariant> EmojiModel::_tones = {
|
||||||
|
|||||||
@@ -51,11 +51,18 @@ class EmojiModel : public QAbstractListModel
|
|||||||
Q_PROPERTY(QVariantList categories READ categories CONSTANT)
|
Q_PROPERTY(QVariantList categories READ categories CONSTANT)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit EmojiModel(QObject *parent = nullptr);
|
static EmojiModel &instance()
|
||||||
|
{
|
||||||
|
static EmojiModel _instance;
|
||||||
|
return _instance;
|
||||||
|
}
|
||||||
|
|
||||||
enum RoleNames {
|
enum RoleNames {
|
||||||
TextRole = Qt::DisplayRole,
|
ShortNameRole = Qt::DisplayRole,
|
||||||
UnicodeRole,
|
UnicodeRole,
|
||||||
|
InvalidRole = 50,
|
||||||
|
DisplayRole = 51,
|
||||||
|
ReplacedTextRole = 52,
|
||||||
};
|
};
|
||||||
Q_ENUM(RoleNames);
|
Q_ENUM(RoleNames);
|
||||||
|
|
||||||
@@ -100,4 +107,5 @@ private:
|
|||||||
|
|
||||||
// TODO: Port away from QSettings
|
// TODO: Port away from QSettings
|
||||||
QSettings m_settings;
|
QSettings m_settings;
|
||||||
|
EmojiModel(QObject *parent = nullptr);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -203,7 +203,7 @@ int main(int argc, char *argv[])
|
|||||||
qmlRegisterSingletonInstance("org.kde.neochat", 1, 0, "FileType", &fileTypeSingleton);
|
qmlRegisterSingletonInstance("org.kde.neochat", 1, 0, "FileType", &fileTypeSingleton);
|
||||||
qmlRegisterSingletonInstance("org.kde.neochat", 1, 0, "LoginHelper", login);
|
qmlRegisterSingletonInstance("org.kde.neochat", 1, 0, "LoginHelper", login);
|
||||||
qmlRegisterSingletonInstance("org.kde.neochat", 1, 0, "UrlHelper", &urlHelper);
|
qmlRegisterSingletonInstance("org.kde.neochat", 1, 0, "UrlHelper", &urlHelper);
|
||||||
qmlRegisterSingletonInstance("org.kde.neochat", 1, 0, "EmojiModel", new EmojiModel(&app));
|
qmlRegisterSingletonInstance("org.kde.neochat", 1, 0, "EmojiModel", &EmojiModel::instance());
|
||||||
#ifdef QUOTIENT_07
|
#ifdef QUOTIENT_07
|
||||||
qmlRegisterSingletonInstance("org.kde.neochat", 1, 0, "AccountRegistry", &Quotient::Accounts);
|
qmlRegisterSingletonInstance("org.kde.neochat", 1, 0, "AccountRegistry", &Quotient::Accounts);
|
||||||
#else
|
#else
|
||||||
|
|||||||
Reference in New Issue
Block a user