Clang-tidy + clang-format

This commit is contained in:
Carl Schwan
2020-11-27 00:19:54 +01:00
parent 49881f809d
commit 136a8f2af8
31 changed files with 470 additions and 332 deletions

View File

@@ -29,8 +29,9 @@ AccountListModel::AccountListModel(QObject *parent)
}
conn->disconnect(this);
const auto it = std::find(m_connections.begin(), m_connections.end(), conn);
if (it == m_connections.end())
if (it == m_connections.end()) {
return; // Already deleted, nothing to do
}
const int row = it - m_connections.begin();
beginRemoveRows(QModelIndex(), row, row);
m_connections.erase(it);

View File

@@ -22,10 +22,10 @@ public:
AccountListModel(QObject *parent = nullptr);
QVariant data(const QModelIndex &index, int role = UserRole) const override;
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
[[nodiscard]] QVariant data(const QModelIndex &index, int role = UserRole) const override;
[[nodiscard]] int rowCount(const QModelIndex &parent = QModelIndex()) const override;
QHash<int, QByteArray> roleNames() const override;
[[nodiscard]] QHash<int, QByteArray> roleNames() const override;
private:
QVector<Connection *> m_connections;

View File

@@ -3,9 +3,9 @@
#include <QQmlFile>
#include <QQmlFileSelector>
#include <QQuickTextDocument>
#include <QStringBuilder>
#include <QTextBlock>
#include <QTextDocument>
#include <QStringBuilder>
#include "neochatroom.h"
@@ -23,11 +23,13 @@ QQuickTextDocument *ChatDocumentHandler::document() const
void ChatDocumentHandler::setDocument(QQuickTextDocument *document)
{
if (document == m_document)
if (document == m_document) {
return;
}
if (m_document)
if (m_document) {
m_document->textDocument()->disconnect(this);
}
m_document = document;
Q_EMIT documentChanged();
}
@@ -39,14 +41,14 @@ int ChatDocumentHandler::cursorPosition() const
void ChatDocumentHandler::setCursorPosition(int position)
{
if (position == m_cursorPosition)
if (position == m_cursorPosition) {
return;
}
m_cursorPosition = position;
Q_EMIT cursorPositionChanged();
}
int ChatDocumentHandler::selectionStart() const
{
return m_selectionStart;
@@ -54,8 +56,9 @@ int ChatDocumentHandler::selectionStart() const
void ChatDocumentHandler::setSelectionStart(int position)
{
if (position == m_selectionStart)
if (position == m_selectionStart) {
return;
}
m_selectionStart = position;
Q_EMIT selectionStartChanged();
@@ -68,8 +71,9 @@ int ChatDocumentHandler::selectionEnd() const
void ChatDocumentHandler::setSelectionEnd(int position)
{
if (position == m_selectionEnd)
if (position == m_selectionEnd) {
return;
}
m_selectionEnd = position;
Q_EMIT selectionEndChanged();
@@ -78,8 +82,9 @@ void ChatDocumentHandler::setSelectionEnd(int position)
QTextCursor ChatDocumentHandler::textCursor() const
{
QTextDocument *doc = textDocument();
if (!doc)
if (!doc) {
return QTextCursor();
}
QTextCursor cursor = QTextCursor(doc);
if (m_selectionStart != m_selectionEnd) {
@@ -93,8 +98,9 @@ QTextCursor ChatDocumentHandler::textCursor() const
QTextDocument *ChatDocumentHandler::textDocument() const
{
if (!m_document)
if (!m_document) {
return nullptr;
}
return m_document->textDocument();
}
@@ -106,8 +112,9 @@ NeoChatRoom *ChatDocumentHandler::room() const
void ChatDocumentHandler::setRoom(NeoChatRoom *room)
{
if (m_room == room)
if (m_room == room) {
return;
}
m_room = room;
Q_EMIT roomChanged();
@@ -123,8 +130,7 @@ QVariantMap ChatDocumentHandler::getAutocompletionInfo()
{"type", AutoCompletionType::Ignore},
};
}
if (m_cursorPosition != m_autoCompleteBeginPosition
&& m_cursorPosition != m_autoCompleteEndPosition) {
if (m_cursorPosition != m_autoCompleteBeginPosition && m_cursorPosition != m_autoCompleteEndPosition) {
// we moved our cursor, so cancel autocompletion
}
@@ -149,12 +155,11 @@ QVariantMap ChatDocumentHandler::getAutocompletionInfo()
{"keyword", autoCompletePrefix},
{"type", AutoCompletionType::User},
};
} else {
return QVariantMap {
{"keyword", autoCompletePrefix},
{"type", AutoCompletionType::Emoji},
};
}
return QVariantMap {
{"keyword", autoCompletePrefix},
{"type", AutoCompletionType::Emoji},
};
}
return QVariantMap {
@@ -164,8 +169,9 @@ QVariantMap ChatDocumentHandler::getAutocompletionInfo()
void ChatDocumentHandler::postMessage(const QString &attachementPath, const QString &replyEventId) const
{
if (!m_room || !m_document)
if (!m_room || !m_document) {
return;
}
QString cleanedText = m_document->textDocument()->toMarkdown();
@@ -175,8 +181,9 @@ void ChatDocumentHandler::postMessage(const QString &attachementPath, const QStr
m_room->uploadFile(attachementPath, cleanedText);
}
if (cleanedText.length() == 0)
if (cleanedText.length() == 0) {
return;
}
auto messageEventType = RoomMessageEvent::MsgType::Text;
@@ -187,7 +194,8 @@ void ChatDocumentHandler::postMessage(const QString &attachementPath, const QStr
if (cleanedText.indexOf(rainbowPrefix) == 0) {
cleanedText = cleanedText.remove(0, rainbowPrefix.length());
QString rainbowText;
QStringList rainbowColors { "#ff2b00", "#ff5500", "#ff8000", "#ffaa00", "#ffd500", "#ffff00", "#d4ff00", "#aaff00", "#80ff00", "#55ff00", "#2bff00", "#00ff00", "#00ff2b", "#00ff55", "#00ff80", "#00ffaa", "#00ffd5", "#00ffff", "#00d4ff", "#00aaff", "#007fff", "#0055ff", "#002bff", "#0000ff", "#2a00ff", "#5500ff", "#7f00ff", "#aa00ff", "#d400ff", "#ff00ff", "#ff00d4", "#ff00aa", "#ff0080", "#ff0055", "#ff002b", "#ff0000" };
QStringList rainbowColors {"#ff2b00", "#ff5500", "#ff8000", "#ffaa00", "#ffd500", "#ffff00", "#d4ff00", "#aaff00", "#80ff00", "#55ff00", "#2bff00", "#00ff00", "#00ff2b", "#00ff55", "#00ff80", "#00ffaa", "#00ffd5", "#00ffff",
"#00d4ff", "#00aaff", "#007fff", "#0055ff", "#002bff", "#0000ff", "#2a00ff", "#5500ff", "#7f00ff", "#aa00ff", "#d400ff", "#ff00ff", "#ff00d4", "#ff00aa", "#ff0080", "#ff0055", "#ff002b", "#ff0000"};
for (int i = 0; i < cleanedText.length(); i++) {
rainbowText = rainbowText % QStringLiteral("<font color='") % rainbowColors.at(i % rainbowColors.length()) % "'>" % cleanedText.at(i) % "</font>";

View File

@@ -34,24 +34,24 @@ public:
};
Q_ENUM(AutoCompletionType)
explicit ChatDocumentHandler(QObject *object = nullptr);
explicit ChatDocumentHandler(QObject *parent = nullptr);
QQuickTextDocument *document() const;
[[nodiscard]] QQuickTextDocument *document() const;
void setDocument(QQuickTextDocument *document);
int cursorPosition() const;
[[nodiscard]] int cursorPosition() const;
void setCursorPosition(int position);
int selectionStart() const;
[[nodiscard]] int selectionStart() const;
void setSelectionStart(int position);
int selectionEnd() const;
[[nodiscard]] int selectionEnd() const;
void setSelectionEnd(int position);
NeoChatRoom *room() const;
[[nodiscard]] NeoChatRoom *room() const;
void setRoom(NeoChatRoom *room);
Q_INVOKABLE void postMessage(const QString &attachmentPath, const QString &replyEventId) const;
Q_INVOKABLE void postMessage(const QString &attachementPath, const QString &replyEventId) const;
/// This function will look at the current QTextCursor and determine if there
/// is the posibility to autocomplete it.
@@ -66,8 +66,8 @@ Q_SIGNALS:
void roomChanged();
private:
QTextCursor textCursor() const;
QTextDocument *textDocument() const;
[[nodiscard]] QTextCursor textCursor() const;
[[nodiscard]] QTextDocument *textDocument() const;
QQuickTextDocument *m_document;

View File

@@ -31,15 +31,17 @@ QImage Clipboard::image() const
return m_clipboard->image();
}
bool Clipboard::saveImage(const QUrl &localPath)
bool Clipboard::saveImage(const QUrl &localPath) const
{
if (!localPath.isLocalFile())
if (!localPath.isLocalFile()) {
return false;
}
auto i = image();
if (i.isNull())
if (i.isNull()) {
return false;
}
QString path = QFileInfo(localPath.toLocalFile()).absolutePath();
QDir dir;

View File

@@ -22,10 +22,10 @@ class Clipboard : public QObject
public:
explicit Clipboard(QObject *parent = nullptr);
bool hasImage() const;
QImage image() const;
[[nodiscard]] bool hasImage() const;
[[nodiscard]] QImage image() const;
Q_INVOKABLE bool saveImage(const QUrl &localPath);
Q_INVOKABLE bool saveImage(const QUrl &localPath) const;
Q_INVOKABLE void saveText(QString message);

View File

@@ -31,14 +31,15 @@
#include <QtGui/QPixmap>
#include <QtNetwork/QAuthenticator>
#include <QtNetwork/QNetworkReply>
#include <utility>
#include "csapi/account-data.h"
#include "csapi/content-repo.h"
#include "csapi/joining.h"
#include "csapi/logout.h"
#include "csapi/profile.h"
#include "csapi/wellknown.h"
#include "csapi/registration.h"
#include "csapi/wellknown.h"
#include "events/eventcontent.h"
#include "events/roommessageevent.h"
#include "neochatroom.h"
@@ -91,7 +92,7 @@ inline QString accessTokenFileName(const AccountSettings &account)
return QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) + '/' + fileName;
}
void Controller::loginWithCredentials(QString serverAddr, QString user, QString pass, QString deviceName)
void Controller::loginWithCredentials(const QString &serverAddr, const QString &user, const QString &pass, QString deviceName)
{
if (user.isEmpty() || pass.isEmpty()) {
return;
@@ -121,17 +122,18 @@ void Controller::loginWithCredentials(QString serverAddr, QString user, QString
account.setHomeserver(finalConn->homeserver());
account.setDeviceId(finalConn->deviceId());
account.setDeviceName(deviceName);
if (!saveAccessTokenToKeyChain(account, finalConn->accessToken()))
if (!saveAccessTokenToKeyChain(account, finalConn->accessToken())) {
qWarning() << "Couldn't save access token";
}
account.sync();
addConnection(finalConn);
setActiveConnection(finalConn);
});
connect(finalConn, &Connection::networkError, [=](QString error, QString, int, int) {
Q_EMIT globalErrorOccured(i18n("Network Error"), error);
connect(finalConn, &Connection::networkError, [=](QString error, const QString &, int, int) {
Q_EMIT globalErrorOccured(i18n("Network Error"), std::move(error));
});
connect(finalConn, &Connection::loginError, [=](QString error, QString) {
Q_EMIT errorOccured(i18n("Login Failed"), error);
connect(finalConn, &Connection::loginError, [=](QString error, const QString &) {
Q_EMIT errorOccured(i18n("Login Failed"), std::move(error));
});
}
});
@@ -142,7 +144,7 @@ void Controller::loginWithCredentials(QString serverAddr, QString user, QString
}
}
void Controller::loginWithAccessToken(QString serverAddr, QString user, QString token, QString deviceName)
void Controller::loginWithAccessToken(const QString &serverAddr, const QString &user, const QString &token, const QString &deviceName)
{
if (user.isEmpty() || token.isEmpty()) {
return;
@@ -162,14 +164,15 @@ void Controller::loginWithAccessToken(QString serverAddr, QString user, QString
account.setHomeserver(conn->homeserver());
account.setDeviceId(conn->deviceId());
account.setDeviceName(deviceName);
if (!saveAccessTokenToKeyChain(account, conn->accessToken()))
if (!saveAccessTokenToKeyChain(account, conn->accessToken())) {
qWarning() << "Couldn't save access token";
}
account.sync();
addConnection(conn);
setActiveConnection(conn);
});
connect(conn, &Connection::networkError, this, [=](QString error, QString, int, int) {
Q_EMIT errorOccured("Network Error", error);
connect(conn, &Connection::networkError, this, [=](QString error, const QString &, int, int) {
Q_EMIT errorOccured("Network Error", std::move(error));
});
conn->connectWithToken(user, token, deviceName);
}
@@ -200,10 +203,11 @@ void Controller::logout(Connection *conn, bool serverSideLogout)
conn->stopSync();
Q_EMIT conn->stateChanged();
Q_EMIT conn->loggedOut();
if (!m_connections.isEmpty())
if (!m_connections.isEmpty()) {
setActiveConnection(m_connections[0]);
else
} else {
setActiveConnection(nullptr);
}
if (!serverSideLogout) {
return;
}
@@ -262,7 +266,7 @@ void Controller::invokeLogin()
c->loadState();
addConnection(c);
});
connect(c, &Connection::loginError, this, [=](QString error, QString) {
connect(c, &Connection::loginError, this, [=](const QString &error, const QString &) {
if (error == "Unrecognised access token") {
Q_EMIT errorOccured(i18n("Login Failed"), i18n("Access Token invalid or revoked"));
logout(c, false);
@@ -271,7 +275,7 @@ void Controller::invokeLogin()
logout(c, true);
}
});
connect(c, &Connection::networkError, this, [=](QString error, QString, int, int) {
connect(c, &Connection::networkError, this, [=](const QString &error, const QString &, int, int) {
Q_EMIT errorOccured("Network Error", error);
});
c->connectWithToken(account.userId(), accessToken, account.deviceId());
@@ -289,8 +293,9 @@ QByteArray Controller::loadAccessTokenFromFile(const AccountSettings &account)
{
QFile accountTokenFile {accessTokenFileName(account)};
if (accountTokenFile.open(QFile::ReadOnly)) {
if (accountTokenFile.size() < 1024)
if (accountTokenFile.size() < 1024) {
return accountTokenFile.readAll();
}
qWarning() << "File" << accountTokenFile.fileName() << "is" << accountTokenFile.size() << "bytes long - too long for a token, ignoring it.";
}
@@ -388,12 +393,13 @@ bool Controller::saveAccessTokenToKeyChain(const AccountSettings &account, const
void Controller::joinRoom(Connection *c, const QString &alias)
{
if (!alias.contains(":"))
if (!alias.contains(":")) {
return;
}
auto knownServer = alias.mid(alias.indexOf(":") + 1);
auto joinRoomJob = c->joinRoom(alias, QStringList {knownServer});
joinRoomJob->connect(joinRoomJob, &JoinRoomJob::failure, [=] {
Quotient::JoinRoomJob::connect(joinRoomJob, &JoinRoomJob::failure, [=] {
Q_EMIT errorOccured("Join Room Failed", joinRoomJob->errorString());
});
}
@@ -401,7 +407,7 @@ void Controller::joinRoom(Connection *c, const QString &alias)
void Controller::createRoom(Connection *c, const QString &name, const QString &topic)
{
auto createRoomJob = c->createRoom(Connection::PublishRoom, "", name, topic, QStringList());
createRoomJob->connect(createRoomJob, &CreateRoomJob::failure, [=] {
Quotient::CreateRoomJob::connect(createRoomJob, &CreateRoomJob::failure, [=] {
Q_EMIT errorOccured("Create Room Failed", createRoomJob->errorString());
});
}
@@ -409,12 +415,12 @@ void Controller::createRoom(Connection *c, const QString &name, const QString &t
void Controller::createDirectChat(Connection *c, const QString &userID)
{
auto createRoomJob = c->createDirectChat(userID);
createRoomJob->connect(createRoomJob, &CreateRoomJob::failure, [=] {
Quotient::CreateRoomJob::connect(createRoomJob, &CreateRoomJob::failure, [=] {
Q_EMIT errorOccured("Create Direct Chat Failed", createRoomJob->errorString());
});
}
void Controller::playAudio(QUrl localFile)
void Controller::playAudio(const QUrl &localFile)
{
auto player = new QMediaPlayer;
player->setMedia(localFile);
@@ -424,7 +430,7 @@ void Controller::playAudio(QUrl localFile)
});
}
void Controller::changeAvatar(Connection *conn, QUrl localFile)
void Controller::changeAvatar(Connection *conn, const QUrl &localFile)
{
auto job = conn->uploadFile(localFile.toLocalFile());
if (isJobRunning(job)) {
@@ -442,7 +448,7 @@ void Controller::markAllMessagesAsRead(Connection *conn)
}
}
void Controller::setAboutData(KAboutData aboutData)
void Controller::setAboutData(const KAboutData &aboutData)
{
m_aboutData = aboutData;
Q_EMIT aboutDataChanged();
@@ -488,7 +494,7 @@ NeochatChangePasswordJob::NeochatChangePasswordJob(const QString &newPassword, b
addParam<>(_data, QStringLiteral("new_password"), newPassword);
addParam<IfNotEmpty>(_data, QStringLiteral("logout_devices"), logoutDevices);
addParam<IfNotEmpty>(_data, QStringLiteral("auth"), auth);
setRequestData(std::move(_data));
setRequestData(_data);
}
QVector<Connection *> Controller::connections() const
@@ -501,7 +507,7 @@ int Controller::accountCount() const
return m_connections.count();
}
bool Controller::quitOnLastWindowClosed() const
bool Controller::quitOnLastWindowClosed()
{
return QApplication::quitOnLastWindowClosed();
}
@@ -530,15 +536,17 @@ void Controller::setBusy(bool busy)
Connection *Controller::activeConnection() const
{
if (m_connection.isNull())
if (m_connection.isNull()) {
return nullptr;
}
return m_connection;
}
void Controller::setActiveConnection(Connection *connection)
{
if (connection == m_connection)
if (connection == m_connection) {
return;
}
m_connection = connection;
Q_EMIT activeConnectionChanged();
}

View File

@@ -33,29 +33,29 @@ class Controller : public QObject
public:
static Controller &instance();
QVector<Connection *> connections() const;
[[nodiscard]] QVector<Connection *> connections() const;
void setActiveConnection(Connection *connection);
Connection *activeConnection() const;
[[nodiscard]] Connection *activeConnection() const;
void addConnection(Connection *c);
void dropConnection(Connection *c);
Q_INVOKABLE void loginWithCredentials(QString, QString, QString, QString);
Q_INVOKABLE void loginWithAccessToken(QString, QString, QString, QString);
Q_INVOKABLE void loginWithCredentials(const QString &, const QString &, const QString &, QString);
Q_INVOKABLE void loginWithAccessToken(const QString &, const QString &, const QString &, const QString &);
Q_INVOKABLE void changePassword(Quotient::Connection *connection, const QString &currentPassword, const QString &newPassword);
int accountCount() const;
[[nodiscard]] int accountCount() const;
bool quitOnLastWindowClosed() const;
[[nodiscard]] static bool quitOnLastWindowClosed();
void setQuitOnLastWindowClosed(bool value);
bool busy() const;
[[nodiscard]] bool busy() const;
void setBusy(bool busy);
void setAboutData(KAboutData aboutData);
KAboutData aboutData() const;
void setAboutData(const KAboutData &aboutData);
[[nodiscard]] KAboutData aboutData() const;
enum PasswordStatus {
Success,
@@ -66,13 +66,13 @@ public:
private:
explicit Controller(QObject *parent = nullptr);
~Controller();
~Controller() override;
QVector<Connection *> m_connections;
QPointer<Connection> m_connection;
bool m_busy = false;
QByteArray loadAccessTokenFromFile(const AccountSettings &account);
static QByteArray loadAccessTokenFromFile(const AccountSettings &account);
QByteArray loadAccessTokenFromKeyChain(const AccountSettings &account);
bool saveAccessTokenToFile(const AccountSettings &account, const QByteArray &accessToken);
@@ -88,20 +88,20 @@ private Q_SLOTS:
Q_SIGNALS:
void busyChanged();
/// Error occured because of user inputs
void errorOccured(QString error, QString detail);
void errorOccured(QString _t1, QString _t2);
/// Error occured because of server or bug in NeoChat
void globalErrorOccured(QString error, QString detail);
void globalErrorOccured(QString _t1, QString _t2);
void syncDone();
void connectionAdded(Quotient::Connection *conn);
void connectionDropped(Quotient::Connection *conn);
void connectionAdded(Quotient::Connection *_t1);
void connectionDropped(Quotient::Connection *_t1);
void initiated();
void notificationClicked(const QString roomId, const QString eventId);
void notificationClicked(const QString &_t1, const QString &_t2);
void quitOnLastWindowClosedChanged();
void unreadCountChanged();
void activeConnectionChanged();
void aboutDataChanged();
void passwordStatus(Controller::PasswordStatus status);
void passwordStatus(Controller::PasswordStatus _t1);
void showWindow();
public Q_SLOTS:
@@ -109,9 +109,9 @@ public Q_SLOTS:
void joinRoom(Quotient::Connection *c, const QString &alias);
void createRoom(Quotient::Connection *c, const QString &name, const QString &topic);
void createDirectChat(Quotient::Connection *c, const QString &userID);
void playAudio(QUrl localFile);
void changeAvatar(Quotient::Connection *conn, QUrl localFile);
void markAllMessagesAsRead(Quotient::Connection *conn);
static void playAudio(const QUrl &localFile);
void changeAvatar(Quotient::Connection *conn, const QUrl &localFile);
static void markAllMessagesAsRead(Quotient::Connection *conn);
};
// TODO libQuotient 0.7: Drop

View File

@@ -70,7 +70,7 @@ QVariantList EmojiModel::filterModel(const QString &filter)
return result;
}
void EmojiModel::emojiUsed(QVariant modelData)
void EmojiModel::emojiUsed(const QVariant &modelData)
{
QVariantList list = history();
@@ -78,8 +78,9 @@ void EmojiModel::emojiUsed(QVariant modelData)
while (it != list.end()) {
if ((*it).value<Emoji>().unicode == modelData.value<Emoji>().unicode) {
it = list.erase(it);
} else
} else {
it++;
}
}
list.push_front(modelData);

View File

@@ -10,16 +10,15 @@
#include <QSettings>
#include <QVariant>
#include <QVector>
#include <utility>
struct Emoji {
Emoji(const QString &u, const QString &s)
: unicode(u)
, shortname(s)
{
}
Emoji()
Emoji(QString u, QString s)
: unicode(std::move(std::move(u)))
, shortname(std::move(std::move(s)))
{
}
Emoji() = default;
friend QDataStream &operator<<(QDataStream &arch, const Emoji &object)
{
@@ -67,13 +66,13 @@ public:
}
Q_INVOKABLE QVariantList history();
Q_INVOKABLE QVariantList filterModel(const QString &filter);
Q_INVOKABLE static QVariantList filterModel(const QString &filter);
Q_SIGNALS:
void historyChanged();
public Q_SLOTS:
void emojiUsed(QVariant modelData);
void emojiUsed(const QVariant &modelData);
private:
static const QVariantList people;

View File

@@ -23,6 +23,7 @@
#include "neochat-version.h"
#include "accountlistmodel.h"
#include "chatdocumenthandler.h"
#include "clipboard.h"
#include "controller.h"
#include "csapi/joining.h"
@@ -30,6 +31,7 @@
#include "emojimodel.h"
#include "matriximageprovider.h"
#include "messageeventmodel.h"
#include "neochatconfig.h"
#include "neochatroom.h"
#include "neochatuser.h"
#include "notificationsmanager.h"
@@ -39,8 +41,6 @@
#include "sortfilterroomlistmodel.h"
#include "userdirectorylistmodel.h"
#include "userlistmodel.h"
#include "neochatconfig.h"
#include "chatdocumenthandler.h"
using namespace Quotient;
@@ -60,8 +60,8 @@ int main(int argc, char *argv[])
QApplication app(argc, argv);
#endif
app.setOrganizationName("KDE");
app.setWindowIcon(QIcon(":/assets/img/icon.png"));
QApplication::setOrganizationName("KDE");
QApplication::setWindowIcon(QIcon(":/assets/img/icon.png"));
KAboutData about(QStringLiteral("neochat"), i18n("Neochat"), QStringLiteral(NEOCHAT_VERSION_STRING), i18n("Matrix client"), KAboutLicense::GPL_V3, i18n("© 2018-2020 Black Hat, 2020 KDE Community"));
about.addAuthor(i18n("Black Hat"), QString(), QStringLiteral("bhat@encom.eu.org"));
@@ -123,14 +123,15 @@ int main(int argc, char *argv[])
engine.addImageProvider(QLatin1String("mxc"), new MatrixImageProvider);
engine.load(QUrl(QStringLiteral("qrc:/qml/main.qml")));
if (engine.rootObjects().isEmpty())
if (engine.rootObjects().isEmpty()) {
return -1;
}
#ifndef Q_OS_ANDROID
QObject::connect(&service, &KDBusService::activateRequested, &engine, [&engine](const QStringList &/*arguments*/, const QString &/*workingDirectory*/) {
QObject::connect(&service, &KDBusService::activateRequested, &engine, [&engine](const QStringList & /*arguments*/, const QString & /*workingDirectory*/) {
const auto rootObjects = engine.rootObjects();
for (auto obj : rootObjects) {
auto view = qobject_cast<QQuickWindow*>(obj);
auto view = qobject_cast<QQuickWindow *>(obj);
if (view) {
view->raise();
return;
@@ -138,5 +139,5 @@ int main(int argc, char *argv[])
}
});
#endif
return app.exec();
return QApplication::exec();
}

View File

@@ -73,8 +73,9 @@ void ThumbnailResponse::prepareResult()
QString localPath = QFileInfo(localFile).absolutePath();
QDir dir;
if (!dir.exists(localPath))
if (!dir.exists(localPath)) {
dir.mkpath(localPath);
}
image.save(localFile);

View File

@@ -5,6 +5,7 @@
*/
#include "messageeventmodel.h"
#include "neochatconfig.h"
#include <connection.h>
#include <events/reactionevent.h>
#include <events/redactionevent.h>
@@ -12,11 +13,10 @@
#include <events/roommemberevent.h>
#include <events/simplestateevents.h>
#include <user.h>
#include "neochatconfig.h"
#include <QDebug>
#include <QTimeZone>
#include <QQmlEngine> // for qmlRegisterType()
#include <QTimeZone>
#include <KLocalizedString>
@@ -70,14 +70,13 @@ MessageEventModel::MessageEventModel(QObject *parent)
});
}
MessageEventModel::~MessageEventModel()
{
}
MessageEventModel::~MessageEventModel() = default;
void MessageEventModel::setRoom(NeoChatRoom *room)
{
if (room == m_currentRoom)
if (room == m_currentRoom) {
return;
}
beginResetModel();
if (m_currentRoom) {
@@ -93,8 +92,9 @@ void MessageEventModel::setRoom(NeoChatRoom *room)
beginInsertRows({}, timelineBaseIndex(), timelineBaseIndex() + int(events.size()) - 1);
});
connect(m_currentRoom, &Room::aboutToAddHistoricalMessages, this, [=](RoomEventsRange events) {
if (rowCount() > 0)
if (rowCount() > 0) {
rowBelowInserted = rowCount() - 1; // See #312
}
beginInsertRows({}, rowCount(), rowCount() + int(events.size()) - 1);
});
connect(m_currentRoom, &Room::addedMessages, this, [=](int lowest, int biggest) {
@@ -103,16 +103,18 @@ void MessageEventModel::setRoom(NeoChatRoom *room)
auto rowBelowInserted = m_currentRoom->maxTimelineIndex() - biggest + timelineBaseIndex() - 1;
refreshEventRoles(rowBelowInserted, {ShowAuthorRole});
}
for (auto i = m_currentRoom->maxTimelineIndex() - biggest; i <= m_currentRoom->maxTimelineIndex() - lowest; ++i)
for (auto i = m_currentRoom->maxTimelineIndex() - biggest; i <= m_currentRoom->maxTimelineIndex() - lowest; ++i) {
refreshLastUserEvents(i);
}
});
connect(m_currentRoom, &Room::pendingEventAboutToAdd, this, [this] {
beginInsertRows({}, 0, 0);
});
connect(m_currentRoom, &Room::pendingEventAdded, this, &MessageEventModel::endInsertRows);
connect(m_currentRoom, &Room::pendingEventAboutToMerge, this, [this](RoomEvent *, int i) {
if (i == 0)
if (i == 0) {
return; // No need to move anything, just refresh
}
movingEvent = true;
// Reverse i because row 0 is bottommost in the model
@@ -126,10 +128,12 @@ void MessageEventModel::setRoom(NeoChatRoom *room)
}
refreshRow(timelineBaseIndex()); // Refresh the looks
refreshLastUserEvents(0);
if (m_currentRoom->timelineSize() > 1) // Refresh above
if (m_currentRoom->timelineSize() > 1) { // Refresh above
refreshEventRoles(timelineBaseIndex() + 1, {ReadMarkerRole});
if (timelineBaseIndex() > 0) // Refresh below, see #312
}
if (timelineBaseIndex() > 0) { // Refresh below, see #312
refreshEventRoles(timelineBaseIndex() - 1, {ShowAuthorRole});
}
});
connect(m_currentRoom, &Room::pendingEventChanged, this, &MessageEventModel::refreshRow);
connect(m_currentRoom, &Room::pendingEventAboutToDiscard, this, [this](int i) {
@@ -153,7 +157,7 @@ void MessageEventModel::setRoom(NeoChatRoom *room)
connect(m_currentRoom, &Room::fileTransferCompleted, this, &MessageEventModel::refreshEvent);
connect(m_currentRoom, &Room::fileTransferFailed, this, &MessageEventModel::refreshEvent);
connect(m_currentRoom, &Room::fileTransferCancelled, this, &MessageEventModel::refreshEvent);
connect(m_currentRoom, &Room::readMarkerForUserMoved, this, [=](User *, QString fromEventId, QString toEventId) {
connect(m_currentRoom, &Room::readMarkerForUserMoved, this, [=](User *, const QString &fromEventId, const QString &toEventId) {
refreshEventRoles(fromEventId, {UserMarkerRole});
refreshEventRoles(toEventId, {UserMarkerRole});
});
@@ -162,8 +166,9 @@ void MessageEventModel::setRoom(NeoChatRoom *room)
endResetModel();
});
qDebug() << "Connected to room" << room->id() << "as" << room->localUser()->id();
} else
} else {
lastReadEventId.clear();
}
endResetModel();
}
@@ -195,9 +200,9 @@ int MessageEventModel::refreshEventRoles(const QString &id, const QVector<int> &
int row = -1;
// First try pendingEvents because it is almost always very short.
const auto pendingIt = m_currentRoom->findPendingEvent(id);
if (pendingIt != m_currentRoom->pendingEvents().end())
if (pendingIt != m_currentRoom->pendingEvents().end()) {
row = int(pendingIt - m_currentRoom->pendingEvents().begin());
else {
} else {
const auto timelineIt = m_currentRoom->findInTimeline(id);
if (timelineIt == m_currentRoom->timelineEdge()) {
qWarning() << "Trying to refresh inexistent event:" << id;
@@ -218,43 +223,51 @@ QDateTime MessageEventModel::makeMessageTimestamp(const Quotient::Room::rev_iter
{
const auto &timeline = m_currentRoom->messageEvents();
auto ts = baseIt->event()->originTimestamp();
if (ts.isValid())
if (ts.isValid()) {
return ts;
}
// The event is most likely redacted or just invalid.
// Look for the nearest date around and slap zero time to it.
using Quotient::TimelineItem;
auto rit = std::find_if(baseIt, timeline.rend(), hasValidTimestamp);
if (rit != timeline.rend())
if (rit != timeline.rend()) {
return {rit->event()->originTimestamp().date(), {0, 0}, Qt::LocalTime};
};
auto it = std::find_if(baseIt.base(), timeline.end(), hasValidTimestamp);
if (it != timeline.end())
if (it != timeline.end()) {
return {it->event()->originTimestamp().date(), {0, 0}, Qt::LocalTime};
};
// What kind of room is that?..
qCritical() << "No valid timestamps in the room timeline!";
return {};
}
QString MessageEventModel::renderDate(QDateTime timestamp) const
QString MessageEventModel::renderDate(const QDateTime &timestamp)
{
auto date = timestamp.toLocalTime().date();
if (date == QDate::currentDate())
if (date == QDate::currentDate()) {
return i18n("Today");
if (date == QDate::currentDate().addDays(-1))
}
if (date == QDate::currentDate().addDays(-1)) {
return i18n("Yesterday");
if (date == QDate::currentDate().addDays(-2))
}
if (date == QDate::currentDate().addDays(-2)) {
return i18n("The day before yesterday");
if (date > QDate::currentDate().addDays(-7))
}
if (date > QDate::currentDate().addDays(-7)) {
return date.toString("dddd");
}
return QLocale::system().toString(date, QLocale::ShortFormat);
}
void MessageEventModel::refreshLastUserEvents(int baseTimelineRow)
{
if (!m_currentRoom || m_currentRoom->timelineSize() <= baseTimelineRow)
if (!m_currentRoom || m_currentRoom->timelineSize() <= baseTimelineRow) {
return;
}
const auto &timelineBottom = m_currentRoom->messageEvents().rbegin();
const auto &lastSender = (*(timelineBottom + baseTimelineRow))->senderId();
@@ -269,8 +282,9 @@ void MessageEventModel::refreshLastUserEvents(int baseTimelineRow)
int MessageEventModel::rowCount(const QModelIndex &parent) const
{
if (!m_currentRoom || parent.isValid())
if (!m_currentRoom || parent.isValid()) {
return 0;
}
return m_currentRoom->timelineSize();
}
@@ -292,8 +306,9 @@ QVariant MessageEventModel::data(const QModelIndex &idx, int role) const
{
const auto row = idx.row();
if (!m_currentRoom || row < 0 || row >= int(m_currentRoom->pendingEvents().size()) + m_currentRoom->timelineSize())
if (!m_currentRoom || row < 0 || row >= int(m_currentRoom->pendingEvents().size()) + m_currentRoom->timelineSize()) {
return {};
};
bool isPending = row < timelineBaseIndex();
const auto timelineIt = m_currentRoom->messageEvents().crbegin() + std::max(0, row - timelineBaseIndex());
@@ -338,14 +353,16 @@ QVariant MessageEventModel::data(const QModelIndex &idx, int role) const
return "message";
}
if (evt.isStateEvent())
if (evt.isStateEvent()) {
return "state";
}
return "other";
}
if (role == EventResolvedTypeRole)
if (role == EventResolvedTypeRole) {
return EventTypeRegistry::getMatrixType(evt.type());
}
if (role == AuthorRole) {
auto author = static_cast<NeoChatUser *>(isPending ? m_currentRoom->localUser() : m_currentRoom->user(evt.senderId()));
@@ -374,29 +391,36 @@ QVariant MessageEventModel::data(const QModelIndex &idx, int role) const
};
}
if (role == HighlightRole)
if (role == HighlightRole) {
return m_currentRoom->isEventHighlighted(&evt);
}
if (role == ReadMarkerRole)
if (role == ReadMarkerRole) {
return evt.id() == lastReadEventId && row > timelineBaseIndex();
}
if (role == SpecialMarksRole) {
if (isPending)
if (isPending) {
return pendingIt->deliveryStatus();
}
auto *memberEvent = timelineIt->viewAs<RoomMemberEvent>();
if (memberEvent) {
if ((memberEvent->isJoin() || memberEvent->isLeave()) && !NeoChatConfig::self()->showLeaveJoinEvent())
if ((memberEvent->isJoin() || memberEvent->isLeave()) && !NeoChatConfig::self()->showLeaveJoinEvent()) {
return EventStatus::Hidden;
}
}
if (is<RedactionEvent>(evt) || is<ReactionEvent>(evt))
if (is<RedactionEvent>(evt) || is<ReactionEvent>(evt)) {
return EventStatus::Hidden;
if (evt.isRedacted())
}
if (evt.isRedacted()) {
return EventStatus::Hidden;
}
if (evt.isStateEvent() && static_cast<const StateEventBase &>(evt).repeatsState())
if (evt.isStateEvent() && static_cast<const StateEventBase &>(evt).repeatsState()) {
return EventStatus::Hidden;
}
if (auto e = eventCast<const RoomMessageEvent>(&evt)) {
if (!e->replacedEvent().isEmpty() && e->replacedEvent() != e->id()) {
@@ -404,24 +428,30 @@ QVariant MessageEventModel::data(const QModelIndex &idx, int role) const
}
}
if (m_currentRoom->connection()->isIgnored(m_currentRoom->user(evt.senderId())))
if (m_currentRoom->connection()->isIgnored(m_currentRoom->user(evt.senderId()))) {
return EventStatus::Hidden;
}
return EventStatus::Normal;
}
if (role == EventIdRole)
if (role == EventIdRole) {
return !evt.id().isEmpty() ? evt.id() : evt.transactionId();
if (role == LongOperationRole) {
if (auto e = eventCast<const RoomMessageEvent>(&evt))
if (e->hasFileContent())
return QVariant::fromValue(m_currentRoom->fileTransferInfo(e->id()));
}
if (role == AnnotationRole)
if (isPending)
if (role == LongOperationRole) {
if (auto e = eventCast<const RoomMessageEvent>(&evt)) {
if (e->hasFileContent()) {
return QVariant::fromValue(m_currentRoom->fileTransferInfo(e->id()));
}
}
}
if (role == AnnotationRole) {
if (isPending) {
return pendingIt->annotation();
}
}
if (role == TimeRole || role == SectionRole) {
auto ts = isPending ? pendingIt->lastUpdated() : makeMessageTimestamp(timelineIt);
@@ -432,8 +462,9 @@ QVariant MessageEventModel::data(const QModelIndex &idx, int role) const
QVariantList variantList;
const auto users = m_currentRoom->usersAtEventId(evt.id());
for (User *user : users) {
if (user == m_currentRoom->localUser())
if (user == m_currentRoom->localUser()) {
continue;
}
variantList.append(QVariant::fromValue(user));
}
return variantList;
@@ -441,11 +472,13 @@ QVariant MessageEventModel::data(const QModelIndex &idx, int role) const
if (role == ReplyRole) {
const QString &replyEventId = evt.contentJson()["m.relates_to"].toObject()["m.in_reply_to"].toObject()["event_id"].toString();
if (replyEventId.isEmpty())
if (replyEventId.isEmpty()) {
return {};
};
const auto replyIt = m_currentRoom->findInTimeline(replyEventId);
if (replyIt == m_currentRoom->timelineEdge())
if (replyIt == m_currentRoom->timelineEdge()) {
return {};
};
const auto &replyEvt = **replyIt;
return QVariantMap {{"eventId", replyEventId}, {"display", m_currentRoom->eventToString(replyEvt, Qt::RichText)}, {"author", userAtEvent(static_cast<NeoChatUser *>(m_currentRoom->user(replyEvt.senderId())), m_currentRoom, evt)}};
@@ -477,14 +510,17 @@ QVariant MessageEventModel::data(const QModelIndex &idx, int role) const
if (role == ReactionRole) {
const auto &annotations = m_currentRoom->relatedEvents(evt, EventRelation::Annotation());
if (annotations.isEmpty())
if (annotations.isEmpty()) {
return {};
};
QMap<QString, QList<NeoChatUser *>> reactions = {};
for (const auto &a : annotations) {
if (a->isRedacted()) // Just in case?
if (a->isRedacted()) { // Just in case?
continue;
if (auto e = eventCast<const ReactionEvent>(a))
}
if (auto e = eventCast<const ReactionEvent>(a)) {
reactions[e->relation().key].append(static_cast<NeoChatUser *>(m_currentRoom->user(e->senderId())));
}
}
if (reactions.isEmpty()) {

View File

@@ -55,17 +55,17 @@ public:
explicit MessageEventModel(QObject *parent = nullptr);
~MessageEventModel() override;
NeoChatRoom *room() const
[[nodiscard]] NeoChatRoom *room() const
{
return m_currentRoom;
}
void setRoom(NeoChatRoom *room);
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
QHash<int, QByteArray> roleNames() const override;
[[nodiscard]] int rowCount(const QModelIndex &parent = QModelIndex()) const override;
[[nodiscard]] QVariant data(const QModelIndex &idx, int role = Qt::DisplayRole) const override;
[[nodiscard]] QHash<int, QByteArray> roleNames() const override;
Q_INVOKABLE int eventIDToIndex(const QString &eventID) const;
Q_INVOKABLE [[nodiscard]] int eventIDToIndex(const QString &eventID) const;
private Q_SLOTS:
int refreshEvent(const QString &eventId);
@@ -75,13 +75,13 @@ private:
NeoChatRoom *m_currentRoom = nullptr;
QString lastReadEventId;
int rowBelowInserted = -1;
bool movingEvent = 0;
bool movingEvent = false;
int timelineBaseIndex() const;
QDateTime makeMessageTimestamp(const Quotient::Room::rev_iter_t &baseIt) const;
QString renderDate(QDateTime timestamp) const;
[[nodiscard]] int timelineBaseIndex() const;
[[nodiscard]] QDateTime makeMessageTimestamp(const Quotient::Room::rev_iter_t &baseIt) const;
[[nodiscard]] static QString renderDate(const QDateTime &timestamp);
void refreshLastUserEvents(int baseRow);
void refreshLastUserEvents(int baseTimelineRow);
void refreshEventRoles(int row, const QVector<int> &roles = {});
int refreshEventRoles(const QString &eventId, const QVector<int> &roles = {});

View File

@@ -29,9 +29,9 @@
#include "events/roompowerlevelsevent.h"
#include "events/typingevent.h"
#include "jobs/downloadfilejob.h"
#include "notificationsmanager.h"
#include "user.h"
#include "utils.h"
#include "notificationsmanager.h"
#include <KLocalizedString>
@@ -45,14 +45,17 @@ NeoChatRoom::NeoChatRoom(Connection *connection, QString roomId, JoinState joinS
setHasFileUploading(false);
});
connect(this, &NeoChatRoom::notificationCountChanged, this, [this]() {
if(messageEvents().size() == 0)
if (messageEvents().size() == 0) {
return;
}
const RoomEvent *lastEvent = messageEvents().rbegin()->get();
if (lastEvent->isStateEvent())
if (lastEvent->isStateEvent()) {
return;
}
User *sender = user(lastEvent->senderId());
if (sender == localUser())
if (sender == localUser()) {
return;
}
NotificationsManager::instance().postNotification(id(), lastEvent->id(), displayName(), sender->displayname(this), eventToString(*lastEvent), avatar(128));
});
@@ -62,24 +65,25 @@ NeoChatRoom::NeoChatRoom(Connection *connection, QString roomId, JoinState joinS
void NeoChatRoom::uploadFile(const QUrl &url, const QString &body)
{
if (url.isEmpty())
if (url.isEmpty()) {
return;
}
QString txnId = postFile(body.isEmpty() ? url.fileName() : body, url, false);
setHasFileUploading(true);
connect(this, &Room::fileTransferCompleted, [=](QString id, QUrl /*localFile*/, QUrl /*mxcUrl*/) {
connect(this, &Room::fileTransferCompleted, [=](const QString &id, const QUrl & /*localFile*/, const QUrl & /*mxcUrl*/) {
if (id == txnId) {
setFileUploadingProgress(0);
setHasFileUploading(false);
}
});
connect(this, &Room::fileTransferFailed, [=](QString id, QString /*error*/) {
connect(this, &Room::fileTransferFailed, [=](const QString &id, const QString & /*error*/) {
if (id == txnId) {
setFileUploadingProgress(0);
setHasFileUploading(false);
}
});
connect(this, &Room::fileTransferProgress, [=](QString id, qint64 progress, qint64 total) {
connect(this, &Room::fileTransferProgress, [=](const QString &id, qint64 progress, qint64 total) {
if (id == txnId) {
qDebug() << "Progress:" << progress << total;
setFileUploadingProgress(int(float(progress) / float(total) * 100));
@@ -118,13 +122,16 @@ QString NeoChatRoom::lastEvent() const
for (auto i = messageEvents().rbegin(); i < messageEvents().rend(); i++) {
const RoomEvent *evt = i->get();
if (is<RedactionEvent>(*evt) || is<ReactionEvent>(*evt))
if (is<RedactionEvent>(*evt) || is<ReactionEvent>(*evt)) {
continue;
if (evt->isRedacted())
}
if (evt->isRedacted()) {
continue;
}
if (evt->isStateEvent() && static_cast<const StateEventBase &>(*evt).repeatsState())
if (evt->isStateEvent() && static_cast<const StateEventBase &>(*evt).repeatsState()) {
continue;
}
if (auto e = eventCast<const RoomMessageEvent>(evt)) {
if (!e->replacedEvent().isEmpty() && e->replacedEvent() != e->id()) {
@@ -132,8 +139,9 @@ QString NeoChatRoom::lastEvent() const
}
}
if (connection()->isIgnored(user(evt->senderId())))
if (connection()->isIgnored(user(evt->senderId()))) {
continue;
}
return user(evt->senderId())->displayname() + (evt->isStateEvent() ? " " : ": ") + eventToString(*evt);
}
@@ -148,12 +156,14 @@ bool NeoChatRoom::isEventHighlighted(const RoomEvent *e) const
void NeoChatRoom::checkForHighlights(const Quotient::TimelineItem &ti)
{
auto localUserId = localUser()->id();
if (ti->senderId() == localUserId)
if (ti->senderId() == localUserId) {
return;
}
if (auto *e = ti.viewAs<RoomMessageEvent>()) {
const auto &text = e->plainBody();
if (text.contains(localUserId) || text.contains(roomMembername(localUserId)))
if (text.contains(localUserId) || text.contains(roomMembername(localUserId))) {
highlights.insert(e);
}
}
}
@@ -190,8 +200,9 @@ void NeoChatRoom::countChanged()
QDateTime NeoChatRoom::lastActiveTime() const
{
if (timelineSize() == 0)
if (timelineSize() == 0) {
return QDateTime();
}
return messageEvents().rbegin()->get()->originTimestamp();
}
@@ -207,8 +218,9 @@ int NeoChatRoom::savedBottomVisibleIndex() const
void NeoChatRoom::saveViewport(int topIndex, int bottomIndex)
{
if (topIndex == -1 || bottomIndex == -1 || (bottomIndex == savedBottomVisibleIndex() && (bottomIndex == 0 || topIndex == savedTopVisibleIndex())))
if (topIndex == -1 || bottomIndex == -1 || (bottomIndex == savedBottomVisibleIndex() && (bottomIndex == 0 || topIndex == savedTopVisibleIndex()))) {
return;
}
if (bottomIndex == 0) {
setFirstDisplayedEventId({});
setLastDisplayedEventId({});
@@ -222,15 +234,16 @@ QVariantList NeoChatRoom::getUsers(const QString &keyword) const
{
const auto userList = users();
QVariantList matchedList;
for (const auto u : userList)
for (const auto u : userList) {
if (u->displayname(this).contains(keyword, Qt::CaseInsensitive)) {
matchedList.append(QVariant::fromValue(u));
}
}
return matchedList;
}
QUrl NeoChatRoom::urlToMxcUrl(QUrl mxcUrl)
QUrl NeoChatRoom::urlToMxcUrl(const QUrl &mxcUrl)
{
return DownloadFileJob::makeRequestUrl(connection()->homeserver(), mxcUrl);
}
@@ -268,7 +281,7 @@ QString NeoChatRoom::eventToString(const RoomEvent &evt, Qt::TextFormat format,
if (removeReply) {
htmlBody.remove(utils::removeRichReplyRegex);
}
htmlBody.replace(utils::userPillRegExp, "<b class=\"user-pill\">\\1</b>");
htmlBody.replace(utils::userPillRegExp, R"(<b class="user-pill">\1</b>)");
htmlBody.replace(utils::strikethroughRegExp, "<s>\\1</s>");
return htmlBody;
@@ -309,30 +322,35 @@ QString NeoChatRoom::eventToString(const RoomEvent &evt, Qt::TextFormat format,
// The below code assumes senderName output in AuthorRole
switch (e.membership()) {
case MembershipType::Invite:
if (e.repeatsState())
if (e.repeatsState()) {
return i18n("reinvited %1 to the room", subjectName);
}
case MembershipType::Join: {
if (e.repeatsState())
if (e.repeatsState()) {
return i18n("joined the room (repeated)");
}
if (!e.prevContent() || e.membership() != e.prevContent()->membership) {
return e.membership() == MembershipType::Invite ? i18n("invited %1 to the room", subjectName) : i18n("joined the room");
}
QString text {};
if (e.isRename()) {
if (e.displayName().isEmpty())
if (e.displayName().isEmpty()) {
text = i18n("cleared their display name");
else
} else {
text = i18n("changed their display name to %1", e.displayName().toHtmlEscaped());
}
}
if (e.isAvatarUpdate()) {
if (!text.isEmpty())
if (!text.isEmpty()) {
text += i18n(" and ");
if (e.avatarUrl().isEmpty())
}
if (e.avatarUrl().isEmpty()) {
text += i18n("cleared their avatar");
else if (e.prevContent()->avatarUrl.isEmpty())
} else if (e.prevContent()->avatarUrl.isEmpty()) {
text += i18n("set an avatar");
else
} else {
text += i18n("updated their avatar");
}
}
return text;
}
@@ -378,7 +396,7 @@ QString NeoChatRoom::eventToString(const RoomEvent &evt, Qt::TextFormat format,
i18n("Unknown event"));
}
void NeoChatRoom::changeAvatar(QUrl localFile)
void NeoChatRoom::changeAvatar(const QUrl &localFile)
{
const auto job = connection()->uploadFile(localFile.toLocalFile());
if (isJobRunning(job)) {
@@ -391,8 +409,9 @@ void NeoChatRoom::changeAvatar(QUrl localFile)
void NeoChatRoom::addLocalAlias(const QString &alias)
{
auto a = aliases();
if (a.contains(alias))
if (a.contains(alias)) {
return;
}
a += alias;
@@ -402,8 +421,9 @@ void NeoChatRoom::addLocalAlias(const QString &alias)
void NeoChatRoom::removeLocalAlias(const QString &alias)
{
auto a = aliases();
if (!a.contains(alias))
if (!a.contains(alias)) {
return;
}
a.removeAll(alias);
@@ -467,8 +487,9 @@ void NeoChatRoom::postPlainMessage(const QString &text, MessageEventType type, c
{
bool isReply = !replyEventId.isEmpty();
const auto replyIt = findInTimeline(replyEventId);
if (replyIt == timelineEdge())
if (replyIt == timelineEdge()) {
isReply = false;
}
if (isReply) {
const auto &replyEvt = **replyIt;
@@ -511,8 +532,9 @@ void NeoChatRoom::postHtmlMessage(const QString &text, const QString &html, Mess
{
bool isReply = !replyEventId.isEmpty();
const auto replyIt = findInTimeline(replyEventId);
if (replyIt == timelineEdge())
if (replyIt == timelineEdge()) {
isReply = false;
}
if (isReply) {
const auto &replyEvt = **replyIt;
@@ -553,12 +575,14 @@ void NeoChatRoom::postHtmlMessage(const QString &text, const QString &html, Mess
void NeoChatRoom::toggleReaction(const QString &eventId, const QString &reaction)
{
if (eventId.isEmpty() || reaction.isEmpty())
if (eventId.isEmpty() || reaction.isEmpty()) {
return;
}
const auto eventIt = findInTimeline(eventId);
if (eventIt == timelineEdge())
if (eventIt == timelineEdge()) {
return;
}
const auto &evt = **eventIt;
@@ -568,8 +592,9 @@ void NeoChatRoom::toggleReaction(const QString &eventId, const QString &reaction
if (!annotations.isEmpty()) {
for (const auto &a : annotations) {
if (auto e = eventCast<const ReactionEvent>(a)) {
if (e->relation().key != reaction)
if (e->relation().key != reaction) {
continue;
}
if (e->senderId() == localUser()->id()) {
redactEventIds.push_back(e->id());
@@ -588,12 +613,13 @@ void NeoChatRoom::toggleReaction(const QString &eventId, const QString &reaction
}
}
bool NeoChatRoom::containsUser(QString userID) const
bool NeoChatRoom::containsUser(const QString &userID) const
{
auto u = Room::user(userID);
if (!u)
if (!u) {
return false;
}
return Room::memberJoinState(u) != JoinState::Leave;
}

View File

@@ -35,14 +35,14 @@ class NeoChatRoom : public Room
public:
explicit NeoChatRoom(Connection *connection, QString roomId, JoinState joinState = {});
QVariantList getUsersTyping() const;
[[nodiscard]] QVariantList getUsersTyping() const;
QString lastEvent() const;
[[nodiscard]] QString lastEvent() const;
bool isEventHighlighted(const Quotient::RoomEvent *e) const;
QDateTime lastActiveTime() const;
[[nodiscard]] QDateTime lastActiveTime() const;
bool hasFileUploading() const
[[nodiscard]] bool hasFileUploading() const
{
return m_hasFileUploading;
}
@@ -55,7 +55,7 @@ public:
Q_EMIT hasFileUploadingChanged();
}
int fileUploadingProgress() const
[[nodiscard]] int fileUploadingProgress() const
{
return m_fileUploadingProgress;
}
@@ -68,24 +68,24 @@ public:
Q_EMIT fileUploadingProgressChanged();
}
bool readMarkerLoaded() const;
[[nodiscard]] bool readMarkerLoaded() const;
Q_INVOKABLE int savedTopVisibleIndex() const;
Q_INVOKABLE int savedBottomVisibleIndex() const;
Q_INVOKABLE [[nodiscard]] int savedTopVisibleIndex() const;
Q_INVOKABLE [[nodiscard]] int savedBottomVisibleIndex() const;
Q_INVOKABLE void saveViewport(int topIndex, int bottomIndex);
Q_INVOKABLE QVariantList getUsers(const QString &keyword) const;
Q_INVOKABLE [[nodiscard]] QVariantList getUsers(const QString &keyword) const;
Q_INVOKABLE QUrl urlToMxcUrl(QUrl mxcUrl);
Q_INVOKABLE QUrl urlToMxcUrl(const QUrl &mxcUrl);
QString avatarMediaId() const;
[[nodiscard]] QString avatarMediaId() const;
QString eventToString(const RoomEvent &evt, Qt::TextFormat format = Qt::PlainText, bool removeReply = true) const;
[[nodiscard]] QString eventToString(const RoomEvent &evt, Qt::TextFormat format = Qt::PlainText, bool removeReply = true) const;
Q_INVOKABLE bool containsUser(QString userID) const;
Q_INVOKABLE [[nodiscard]] bool containsUser(const QString &userID) const;
Q_INVOKABLE bool canSendEvent(const QString &eventType) const;
Q_INVOKABLE bool canSendState(const QString &eventType) const;
Q_INVOKABLE [[nodiscard]] bool canSendEvent(const QString &eventType) const;
Q_INVOKABLE [[nodiscard]] bool canSendState(const QString &eventType) const;
private:
QString m_cachedInput;
@@ -100,7 +100,7 @@ private:
void onAddHistoricalTimelineEvents(rev_iter_t from) override;
void onRedaction(const RoomEvent &prevEvent, const RoomEvent &after) override;
static QString markdownToHTML(const QString &plaintext);
static QString markdownToHTML(const QString &markdown);
private Q_SLOTS:
void countChanged();
@@ -121,7 +121,7 @@ public Q_SLOTS:
void postArbitaryMessage(const QString &text, Quotient::RoomMessageEvent::MsgType type, const QString &replyEventId);
void postPlainMessage(const QString &text, Quotient::RoomMessageEvent::MsgType type = Quotient::MessageEventType::Text, const QString &replyEventId = "");
void postHtmlMessage(const QString &text, const QString &html, Quotient::MessageEventType type = Quotient::MessageEventType::Text, const QString &replyEventId = "");
void changeAvatar(QUrl localFile);
void changeAvatar(const QUrl &localFile);
void addLocalAlias(const QString &alias);
void removeLocalAlias(const QString &alias);
void toggleReaction(const QString &eventId, const QString &reaction);

View File

@@ -6,11 +6,12 @@
#include "neochatuser.h"
#include <PlatformTheme> // Kirigami
#include <utility>
#include "csapi/profile.h"
NeoChatUser::NeoChatUser(QString userId, Connection *connection)
: User(userId, connection)
: User(std::move(userId), connection)
{
m_theme = static_cast<Kirigami::PlatformTheme *>(qmlAttachedPropertiesObject<Kirigami::PlatformTheme>(this, true));
Q_ASSERT(m_theme);
@@ -23,10 +24,11 @@ QColor NeoChatUser::color()
return m_color;
}
void NeoChatUser::setColor(QColor color)
void NeoChatUser::setColor(const QColor &color)
{
if (m_color == color)
if (m_color == color) {
return;
}
m_color = color;
emit colorChanged(m_color);

View File

@@ -26,10 +26,10 @@ public:
public Q_SLOTS:
QColor color();
void setColor(QColor color);
void setColor(const QColor &color);
Q_SIGNALS:
void colorChanged(QColor color);
void colorChanged(QColor _t1);
private:
Kirigami::PlatformTheme *m_theme = nullptr;

View File

@@ -19,7 +19,6 @@ NotificationsManager &NotificationsManager::instance()
return _instance;
}
NotificationsManager::NotificationsManager(QObject *parent)
: QObject(parent)
{
@@ -27,7 +26,7 @@ NotificationsManager::NotificationsManager(QObject *parent)
void NotificationsManager::postNotification(const QString &roomid, const QString &eventid, const QString &roomname, const QString &sender, const QString &text, const QImage &icon)
{
if(!NeoChatConfig::self()->showNotifications()) {
if (!NeoChatConfig::self()->showNotifications()) {
return;
}

View File

@@ -12,8 +12,9 @@ PublicRoomListModel::PublicRoomListModel(QObject *parent)
void PublicRoomListModel::setConnection(Connection *conn)
{
if (m_connection == conn)
if (m_connection == conn) {
return;
}
beginResetModel();
@@ -46,8 +47,9 @@ void PublicRoomListModel::setConnection(Connection *conn)
void PublicRoomListModel::setServer(const QString &value)
{
if (m_server == value)
if (m_server == value) {
return;
}
m_server = value;
@@ -74,8 +76,9 @@ void PublicRoomListModel::setServer(const QString &value)
void PublicRoomListModel::setKeyword(const QString &value)
{
if (m_keyword == value)
if (m_keyword == value) {
return;
}
m_keyword = value;
@@ -102,8 +105,9 @@ void PublicRoomListModel::setKeyword(const QString &value)
void PublicRoomListModel::next(int count)
{
if (count < 1)
if (count < 1) {
return;
}
if (job) {
qDebug() << "PublicRoomListModel: Other jobs running, ignore";
@@ -134,8 +138,9 @@ void PublicRoomListModel::next(int count)
QVariant PublicRoomListModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid())
if (!index.isValid()) {
return QVariant();
}
if (index.row() >= rooms.count()) {
qDebug() << "PublicRoomListModel, something's wrong: index.row() >= "
@@ -195,8 +200,9 @@ QVariant PublicRoomListModel::data(const QModelIndex &index, int role) const
return room.worldReadable;
}
if (role == IsJoinedRole) {
if (!m_connection)
if (!m_connection) {
return {};
}
return m_connection->room(room.roomId, JoinState::Join) != nullptr;
}
@@ -223,8 +229,9 @@ QHash<int, QByteArray> PublicRoomListModel::roleNames() const
int PublicRoomListModel::rowCount(const QModelIndex &parent) const
{
if (parent.isValid())
if (parent.isValid()) {
return 0;
}
return rooms.count();
}

View File

@@ -38,30 +38,30 @@ public:
PublicRoomListModel(QObject *parent = nullptr);
QVariant data(const QModelIndex &index, int role = NameRole) const override;
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
[[nodiscard]] QVariant data(const QModelIndex &index, int role = NameRole) const override;
[[nodiscard]] int rowCount(const QModelIndex &parent = QModelIndex()) const override;
QHash<int, QByteArray> roleNames() const override;
[[nodiscard]] QHash<int, QByteArray> roleNames() const override;
Connection *connection() const
[[nodiscard]] Connection *connection() const
{
return m_connection;
}
void setConnection(Connection *value);
void setConnection(Connection *conn);
QString server() const
[[nodiscard]] QString server() const
{
return m_server;
}
void setServer(const QString &value);
QString keyword() const
[[nodiscard]] QString keyword() const
{
return m_keyword;
}
void setKeyword(const QString &value);
bool hasMore() const;
[[nodiscard]] bool hasMore() const;
Q_INVOKABLE void next(int count = 50);

View File

@@ -5,9 +5,9 @@
*/
#include "roomlistmodel.h"
#include "neochatconfig.h"
#include "user.h"
#include "utils.h"
#include "neochatconfig.h"
#include "events/roomevent.h"
@@ -17,6 +17,7 @@
#include <QStandardPaths>
#include <KLocalizedString>
#include <utility>
RoomListModel::RoomListModel(QObject *parent)
: QAbstractListModel(parent)
@@ -27,16 +28,16 @@ RoomListModel::RoomListModel(QObject *parent)
}
}
RoomListModel::~RoomListModel()
{
}
RoomListModel::~RoomListModel() = default;
void RoomListModel::setConnection(Connection *connection)
{
if (connection == m_connection)
if (connection == m_connection) {
return;
if (m_connection)
}
if (m_connection) {
m_connection->disconnect(this);
}
if (!connection) {
qDebug() << "Removing current connection...";
m_connection = nullptr;
@@ -61,13 +62,14 @@ void RoomListModel::setConnection(Connection *connection)
auto refreshRooms = [this, &connection](Quotient::DirectChatsMap rooms) {
for (const QString &roomID : qAsConst(rooms)) {
auto room = connection->room(roomID);
if (room)
if (room) {
refresh(static_cast<NeoChatRoom *>(room));
}
}
};
refreshRooms(additions);
refreshRooms(removals);
refreshRooms(std::move(additions));
refreshRooms(std::move(removals));
});
doResetModel();
@@ -128,29 +130,37 @@ void RoomListModel::connectRoomSignals(NeoChatRoom *room)
refresh(room, {LastEventRole});
});
connect(room, &Room::notificationCountChanged, this, [=] {
if (room->notificationCount() == 0)
if (room->notificationCount() == 0) {
return;
if (room->timelineSize() == 0)
}
if (room->timelineSize() == 0) {
return;
}
const RoomEvent *lastEvent = room->messageEvents().rbegin()->get();
if (lastEvent->isStateEvent())
if (lastEvent->isStateEvent()) {
return;
}
User *sender = room->user(lastEvent->senderId());
if (sender == room->localUser())
if (sender == room->localUser()) {
return;
}
Q_EMIT newMessage(room->id(), lastEvent->id(), room->displayName(), sender->displayname(), room->eventToString(*lastEvent), room->avatar(128));
});
connect(room, &Room::highlightCountChanged, this, [=] {
if (room->highlightCount() == 0)
if (room->highlightCount() == 0) {
return;
if (room->timelineSize() == 0)
}
if (room->timelineSize() == 0) {
return;
}
const RoomEvent *lastEvent = room->messageEvents().rbegin()->get();
if (lastEvent->isStateEvent())
if (lastEvent->isStateEvent()) {
return;
}
User *sender = room->user(lastEvent->senderId());
if (sender == room->localUser())
if (sender == room->localUser()) {
return;
}
Q_EMIT newHighlight(room->id(), lastEvent->id(), room->displayName(), sender->displayname(), room->eventToString(*lastEvent), room->avatar(128));
});
connect(room, &Room::notificationCountChanged, this, &RoomListModel::refreshNotificationCount);
@@ -206,8 +216,9 @@ void RoomListModel::deleteRoom(Room *room)
{
qDebug() << "Deleting room" << room->id();
const auto it = std::find(m_rooms.begin(), m_rooms.end(), room);
if (it == m_rooms.end())
if (it == m_rooms.end()) {
return; // Already deleted, nothing to do
}
qDebug() << "Erasing room" << room->id();
const int row = it - m_rooms.begin();
beginRemoveRows(QModelIndex(), row, row);
@@ -217,57 +228,74 @@ void RoomListModel::deleteRoom(Room *room)
int RoomListModel::rowCount(const QModelIndex &parent) const
{
if (parent.isValid())
if (parent.isValid()) {
return 0;
}
return m_rooms.count();
}
QVariant RoomListModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid())
if (!index.isValid()) {
return QVariant();
}
if (index.row() >= m_rooms.count()) {
qDebug() << "UserListModel: something wrong here...";
return QVariant();
}
NeoChatRoom *room = m_rooms.at(index.row());
if (role == NameRole)
if (role == NameRole) {
return room->displayName();
if (role == AvatarRole)
}
if (role == AvatarRole) {
return room->avatarMediaId();
if (role == TopicRole)
}
if (role == TopicRole) {
return room->topic();
}
if (role == CategoryRole) {
if (room->joinState() == JoinState::Invite)
if (room->joinState() == JoinState::Invite) {
return RoomType::Invited;
if (room->isFavourite())
}
if (room->isFavourite()) {
return RoomType::Favorite;
if (room->isDirectChat())
}
if (room->isDirectChat()) {
return RoomType::Direct;
if (room->isLowPriority())
}
if (room->isLowPriority()) {
return RoomType::Deprioritized;
}
return RoomType::Normal;
}
if (role == UnreadCountRole)
if (role == UnreadCountRole) {
return room->unreadCount();
if (role == NotificationCountRole)
}
if (role == NotificationCountRole) {
return room->notificationCount();
if (role == HighlightCountRole)
}
if (role == HighlightCountRole) {
return room->highlightCount();
if (role == LastEventRole)
}
if (role == LastEventRole) {
return room->lastEvent();
if (role == LastActiveTimeRole)
}
if (role == LastActiveTimeRole) {
return room->lastActiveTime();
}
if (role == JoinStateRole) {
if (!room->successorId().isEmpty())
if (!room->successorId().isEmpty()) {
return QStringLiteral("upgraded");
}
return toCString(room->joinState());
}
if (role == CurrentRoomRole)
if (role == CurrentRoomRole) {
return QVariant::fromValue(room);
if (role == CategoryVisibleRole)
}
if (role == CategoryVisibleRole) {
return m_categoryVisibility.value(data(index, CategoryRole).toInt(), true);
}
return QVariant();
}
@@ -300,7 +328,7 @@ QHash<int, QByteArray> RoomListModel::roleNames() const
return roles;
}
QString RoomListModel::categoryName(int section) const
QString RoomListModel::categoryName(int section)
{
switch (section) {
case 1:

View File

@@ -54,27 +54,27 @@ public:
Q_ENUM(EventRoles)
RoomListModel(QObject *parent = nullptr);
virtual ~RoomListModel() override;
~RoomListModel() override;
Connection *connection() const
[[nodiscard]] Connection *connection() const
{
return m_connection;
}
void setConnection(Connection *connection);
void doResetModel();
Q_INVOKABLE NeoChatRoom *roomAt(int row) const;
Q_INVOKABLE [[nodiscard]] NeoChatRoom *roomAt(int row) const;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
Q_INVOKABLE int rowCount(const QModelIndex &parent = QModelIndex()) const override;
[[nodiscard]] QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
Q_INVOKABLE [[nodiscard]] int rowCount(const QModelIndex &parent = QModelIndex()) const override;
QHash<int, QByteArray> roleNames() const override;
[[nodiscard]] QHash<int, QByteArray> roleNames() const override;
Q_INVOKABLE QString categoryName(int category) const;
Q_INVOKABLE [[nodiscard]] static QString categoryName(int section);
Q_INVOKABLE void setCategoryVisible(int category, bool visible);
Q_INVOKABLE bool categoryVisible(int category) const;
Q_INVOKABLE [[nodiscard]] bool categoryVisible(int category) const;
int notificationCount() const
[[nodiscard]] int notificationCount() const
{
return m_notificationCount;
}
@@ -100,9 +100,9 @@ Q_SIGNALS:
void connectionChanged();
void notificationCountChanged();
void roomAdded(NeoChatRoom *room);
void newMessage(const QString &roomId, const QString &eventId, const QString &roomName, const QString &senderName, const QString &text, const QImage &icon);
void newHighlight(const QString &roomId, const QString &eventId, const QString &roomName, const QString &senderName, const QString &text, const QImage &icon);
void roomAdded(NeoChatRoom *_t1);
void newMessage(const QString &_t1, const QString &_t2, const QString &_t3, const QString &_t4, const QString &_t5, const QImage &_t6);
void newHighlight(const QString &_t1, const QString &_t2, const QString &_t3, const QString &_t4, const QString &_t5, const QImage &_t6);
};
#endif // ROOMLISTMODEL_H

View File

@@ -22,10 +22,11 @@ void SortFilterRoomListModel::setRoomSortOrder(SortFilterRoomListModel::RoomSort
{
m_sortOrder = sortOrder;
Q_EMIT roomSortOrderChanged();
if (sortOrder == SortFilterRoomListModel::Alphabetical)
if (sortOrder == SortFilterRoomListModel::Alphabetical) {
setSortRole(RoomListModel::NameRole);
else if (sortOrder == SortFilterRoomListModel::LastActivity)
} else if (sortOrder == SortFilterRoomListModel::LastActivity) {
setSortRole(RoomListModel::LastActiveTimeRole);
}
invalidate();
}
@@ -43,7 +44,8 @@ bool SortFilterRoomListModel::lessThan(const QModelIndex &source_left, const QMo
if (categoryLeft == RoomType::Types::Favorite && categoryRight == RoomType::Types::Favorite) {
return sourceModel()->data(source_left, RoomListModel::LastActiveTimeRole).toDateTime() > sourceModel()->data(source_right, RoomListModel::LastActiveTimeRole).toDateTime();
} else if (categoryLeft == RoomType::Types::Favorite) {
}
if (categoryLeft == RoomType::Types::Favorite) {
return true;
} else if (categoryRight == RoomType::Types::Favorite) {
return false;
@@ -51,10 +53,12 @@ bool SortFilterRoomListModel::lessThan(const QModelIndex &source_left, const QMo
return sourceModel()->data(source_left, RoomListModel::LastActiveTimeRole).toDateTime() > sourceModel()->data(source_right, RoomListModel::LastActiveTimeRole).toDateTime();
}
if (m_sortOrder != SortFilterRoomListModel::Categories)
if (m_sortOrder != SortFilterRoomListModel::Categories) {
return QSortFilterProxyModel::lessThan(source_left, source_right);
if (sourceModel()->data(source_left, RoomListModel::CategoryRole) != sourceModel()->data(source_right, RoomListModel::CategoryRole))
}
if (sourceModel()->data(source_left, RoomListModel::CategoryRole) != sourceModel()->data(source_right, RoomListModel::CategoryRole)) {
return sourceModel()->data(source_left, RoomListModel::CategoryRole).toInt() < sourceModel()->data(source_right, RoomListModel::CategoryRole).toInt();
}
return sourceModel()->data(source_left, RoomListModel::LastActiveTimeRole).toDateTime() > sourceModel()->data(source_right, RoomListModel::LastActiveTimeRole).toDateTime();
}

View File

@@ -26,15 +26,15 @@ public:
SortFilterRoomListModel(QObject *parent = nullptr);
void setRoomSortOrder(RoomSortOrder sortOrder);
RoomSortOrder roomSortOrder() const;
[[nodiscard]] RoomSortOrder roomSortOrder() const;
void setFilterText(const QString &text);
QString filterText() const;
[[nodiscard]] QString filterText() const;
bool lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const override;
[[nodiscard]] bool lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const override;
protected:
bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const override;
[[nodiscard]] bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const override;
Q_SIGNALS:
void roomSortOrderChanged();

View File

@@ -17,7 +17,7 @@ TrayIcon::TrayIcon(QObject *parent)
auto viewAction_ = new QAction(i18n("Show"), parent);
connect(viewAction_, &QAction::triggered, this, &TrayIcon::showWindow);
connect(this, &KStatusNotifierItem::activateRequested, this, [this] (bool active) {
connect(this, &KStatusNotifierItem::activateRequested, this, [this](bool active) {
if (active) {
Q_EMIT showWindow();
}

View File

@@ -8,12 +8,12 @@
// Modified from mujx/nheko's TrayIcon.
#include <KStatusNotifierItem>
#include <QAction>
#include <QIcon>
#include <QIconEngine>
#include <QPainter>
#include <QRect>
#include <KStatusNotifierItem>
class TrayIcon : public KStatusNotifierItem
{
@@ -29,7 +29,7 @@ public:
}
void setIconSource(const QString &source);
bool isOnline()
bool isOnline() const
{
return m_isOnline;
}

View File

@@ -12,8 +12,9 @@ UserDirectoryListModel::UserDirectoryListModel(QObject *parent)
void UserDirectoryListModel::setConnection(Connection *conn)
{
if (m_connection == conn)
if (m_connection == conn) {
return;
}
beginResetModel();
@@ -40,8 +41,9 @@ void UserDirectoryListModel::setConnection(Connection *conn)
void UserDirectoryListModel::setKeyword(const QString &value)
{
if (m_keyword == value)
if (m_keyword == value) {
return;
}
m_keyword = value;
@@ -59,8 +61,9 @@ void UserDirectoryListModel::setKeyword(const QString &value)
void UserDirectoryListModel::search(int count)
{
if (count < 1)
if (count < 1) {
return;
}
if (job) {
qDebug() << "UserDirectoryListModel: Other jobs running, ignore";
@@ -68,8 +71,9 @@ void UserDirectoryListModel::search(int count)
return;
}
if (attempted)
if (attempted) {
return;
}
job = m_connection->callApi<SearchUserDirectoryJob>(m_keyword, count);
@@ -95,8 +99,9 @@ void UserDirectoryListModel::search(int count)
QVariant UserDirectoryListModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid())
if (!index.isValid()) {
return QVariant();
}
if (index.row() >= users.count()) {
qDebug() << "UserDirectoryListModel, something's wrong: index.row() >= "
@@ -130,8 +135,9 @@ QVariant UserDirectoryListModel::data(const QModelIndex &index, int role) const
return user.userId;
}
if (role == DirectChatsRole) {
if (!m_connection)
if (!m_connection) {
return {};
};
auto userObj = m_connection->user(user.userId);
auto directChats = m_connection->directChats();
@@ -161,8 +167,9 @@ QHash<int, QByteArray> UserDirectoryListModel::roleNames() const
int UserDirectoryListModel::rowCount(const QModelIndex &parent) const
{
if (parent.isValid())
if (parent.isValid()) {
return 0;
}
return users.count();
}

View File

@@ -31,24 +31,24 @@ public:
UserDirectoryListModel(QObject *parent = nullptr);
QVariant data(const QModelIndex &index, int role = NameRole) const override;
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
[[nodiscard]] QVariant data(const QModelIndex &index, int role = NameRole) const override;
[[nodiscard]] int rowCount(const QModelIndex &parent = QModelIndex()) const override;
QHash<int, QByteArray> roleNames() const override;
[[nodiscard]] QHash<int, QByteArray> roleNames() const override;
Connection *connection() const
[[nodiscard]] Connection *connection() const
{
return m_connection;
}
void setConnection(Connection *value);
void setConnection(Connection *conn);
QString keyword() const
[[nodiscard]] QString keyword() const
{
return m_keyword;
}
void setKeyword(const QString &value);
bool limited() const
[[nodiscard]] bool limited() const
{
return m_limited;
}

View File

@@ -25,16 +25,18 @@ UserListModel::UserListModel(QObject *parent)
void UserListModel::setRoom(Quotient::Room *room)
{
if (m_currentRoom == room)
if (m_currentRoom == room) {
return;
}
using namespace Quotient;
beginResetModel();
if (m_currentRoom) {
m_currentRoom->disconnect(this);
// m_currentRoom->connection()->disconnect(this);
for (User *user : qAsConst(m_users))
for (User *user : qAsConst(m_users)) {
user->disconnect(this);
}
m_users.clear();
}
m_currentRoom = room;
@@ -61,15 +63,17 @@ void UserListModel::setRoom(Quotient::Room *room)
Quotient::User *UserListModel::userAt(QModelIndex index) const
{
if (index.row() < 0 || index.row() >= m_users.size())
if (index.row() < 0 || index.row() >= m_users.size()) {
return nullptr;
}
return m_users.at(index.row());
}
QVariant UserListModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid())
if (!index.isValid()) {
return QVariant();
}
if (index.row() >= m_users.count()) {
qDebug() << "UserListModel, something's wrong: index.row() >= m_users.count()";
@@ -132,8 +136,9 @@ QVariant UserListModel::data(const QModelIndex &index, int role) const
int UserListModel::rowCount(const QModelIndex &parent) const
{
if (parent.isValid())
if (parent.isValid()) {
return 0;
}
return m_users.count();
}
@@ -155,23 +160,26 @@ void UserListModel::userRemoved(Quotient::User *user)
m_users.removeAt(pos);
endRemoveRows();
user->disconnect(this);
} else
} else {
qWarning() << "Trying to remove a room member not in the user list";
}
}
void UserListModel::refresh(Quotient::User *user, QVector<int> roles)
void UserListModel::refresh(Quotient::User *user, const QVector<int> &roles)
{
auto pos = findUserPos(user);
if (pos != m_users.size())
if (pos != m_users.size()) {
Q_EMIT dataChanged(index(pos), index(pos), roles);
else
} else {
qWarning() << "Trying to access a room member not in the user list";
}
}
void UserListModel::avatarChanged(Quotient::User *user, const Quotient::Room *context)
{
if(context == m_currentRoom)
if (context == m_currentRoom) {
refresh(user, {AvatarRole});
}
}
int UserListModel::findUserPos(User *user) const

View File

@@ -48,17 +48,17 @@ public:
UserListModel(QObject *parent = nullptr);
Quotient::Room *room() const
[[nodiscard]] Quotient::Room *room() const
{
return m_currentRoom;
}
void setRoom(Quotient::Room *room);
Quotient::User *userAt(QModelIndex index) const;
[[nodiscard]] Quotient::User *userAt(QModelIndex index) const;
QVariant data(const QModelIndex &index, int role = NameRole) const override;
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
[[nodiscard]] QVariant data(const QModelIndex &index, int role = NameRole) const override;
[[nodiscard]] int rowCount(const QModelIndex &parent = QModelIndex()) const override;
QHash<int, QByteArray> roleNames() const override;
[[nodiscard]] QHash<int, QByteArray> roleNames() const override;
Q_SIGNALS:
void roomChanged();
@@ -66,7 +66,7 @@ Q_SIGNALS:
private Q_SLOTS:
void userAdded(Quotient::User *user);
void userRemoved(Quotient::User *user);
void refresh(Quotient::User *user, QVector<int> roles = {});
void refresh(Quotient::User *user, const QVector<int> &roles = {});
void avatarChanged(Quotient::User *user, const Quotient::Room *context);
private:
@@ -74,7 +74,7 @@ private:
QList<Quotient::User *> m_users;
int findUserPos(Quotient::User *user) const;
int findUserPos(const QString &username) const;
[[nodiscard]] int findUserPos(const QString &username) const;
};
#endif // USERLISTMODEL_H