aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorKitsune Ral <Kitsune-Ral@users.sf.net>2021-01-15 08:19:22 +0100
committerGitHub <noreply@github.com>2021-01-15 08:19:22 +0100
commit544ec34b4563aacac6fd5b2f4aa64813096cd4b8 (patch)
tree878a6db1895d75c89292b8278731d63fadf248e1 /lib
parent17d6e00597fdc1c8f25808735cbc728c4a6b3506 (diff)
parentb0d3ecc774ca4aec24bceb5ec1f1ded844a7213a (diff)
downloadlibquotient-544ec34b4563aacac6fd5b2f4aa64813096cd4b8.tar.gz
libquotient-544ec34b4563aacac6fd5b2f4aa64813096cd4b8.zip
Merge branch 'master' into dfaure/stricter-flags
Diffstat (limited to 'lib')
-rw-r--r--lib/avatar.cpp30
-rw-r--r--lib/avatar.h16
-rw-r--r--lib/connection.cpp155
-rw-r--r--lib/connection.h88
-rw-r--r--lib/connectiondata.cpp16
-rw-r--r--lib/connectiondata.h16
-rw-r--r--lib/converters.cpp20
-rw-r--r--lib/converters.h16
-rw-r--r--lib/e2ee.h5
-rw-r--r--lib/encryptionmanager.cpp7
-rw-r--r--lib/encryptionmanager.h4
-rw-r--r--lib/eventitem.cpp16
-rw-r--r--lib/eventitem.h24
-rw-r--r--lib/events/accountdataevents.h16
-rw-r--r--lib/events/callanswerevent.cpp16
-rw-r--r--lib/events/callanswerevent.h16
-rw-r--r--lib/events/callcandidatesevent.cpp16
-rw-r--r--lib/events/callcandidatesevent.h16
-rw-r--r--lib/events/callhangupevent.cpp16
-rw-r--r--lib/events/callhangupevent.h16
-rw-r--r--lib/events/callinviteevent.cpp16
-rw-r--r--lib/events/callinviteevent.h16
-rw-r--r--lib/events/directchatevent.cpp16
-rw-r--r--lib/events/directchatevent.h16
-rw-r--r--lib/events/encryptedevent.cpp4
-rw-r--r--lib/events/encryptedevent.h4
-rw-r--r--lib/events/encryptionevent.h16
-rw-r--r--lib/events/event.cpp19
-rw-r--r--lib/events/event.h57
-rw-r--r--lib/events/eventcontent.cpp16
-rw-r--r--lib/events/eventcontent.h16
-rw-r--r--lib/events/eventloader.h16
-rw-r--r--lib/events/reactionevent.cpp16
-rw-r--r--lib/events/reactionevent.h16
-rw-r--r--lib/events/receiptevent.cpp16
-rw-r--r--lib/events/receiptevent.h16
-rw-r--r--lib/events/redactionevent.cpp4
-rw-r--r--lib/events/redactionevent.h16
-rw-r--r--lib/events/roomavatarevent.h16
-rw-r--r--lib/events/roomcanonicalaliasevent.h16
-rw-r--r--lib/events/roomcreateevent.cpp16
-rw-r--r--lib/events/roomcreateevent.h16
-rw-r--r--lib/events/roomevent.cpp16
-rw-r--r--lib/events/roomevent.h16
-rw-r--r--lib/events/roommemberevent.cpp16
-rw-r--r--lib/events/roommemberevent.h16
-rw-r--r--lib/events/roommessageevent.cpp16
-rw-r--r--lib/events/roommessageevent.h16
-rw-r--r--lib/events/roomtombstoneevent.cpp16
-rw-r--r--lib/events/roomtombstoneevent.h16
-rw-r--r--lib/events/simplestateevents.h16
-rw-r--r--lib/events/stateevent.cpp16
-rw-r--r--lib/events/stateevent.h16
-rw-r--r--lib/events/stickerevent.cpp26
-rw-r--r--lib/events/stickerevent.h38
-rw-r--r--lib/events/typingevent.cpp16
-rw-r--r--lib/events/typingevent.h16
-rw-r--r--lib/jobs/basejob.cpp78
-rw-r--r--lib/jobs/basejob.h36
-rw-r--r--lib/jobs/downloadfilejob.cpp2
-rw-r--r--lib/jobs/mediathumbnailjob.cpp16
-rw-r--r--lib/jobs/mediathumbnailjob.h16
-rw-r--r--lib/jobs/postreadmarkersjob.h38
-rw-r--r--lib/jobs/requestdata.h16
-rw-r--r--lib/jobs/syncjob.cpp16
-rw-r--r--lib/jobs/syncjob.h16
-rw-r--r--lib/joinstate.h16
-rw-r--r--lib/logging.cpp17
-rw-r--r--lib/logging.h17
-rw-r--r--lib/networkaccessmanager.cpp23
-rw-r--r--lib/networkaccessmanager.h16
-rw-r--r--lib/networksettings.cpp16
-rw-r--r--lib/networksettings.h16
-rw-r--r--lib/qt_connection_util.h16
-rw-r--r--lib/quotient_common.h4
-rw-r--r--lib/room.cpp348
-rw-r--r--lib/room.h20
-rw-r--r--lib/settings.h16
-rw-r--r--lib/syncdata.cpp16
-rw-r--r--lib/syncdata.h16
-rw-r--r--lib/uri.cpp66
-rw-r--r--lib/uriresolver.cpp2
-rw-r--r--lib/uriresolver.h2
-rw-r--r--lib/user.cpp20
-rw-r--r--lib/user.h20
-rw-r--r--lib/util.cpp21
-rw-r--r--lib/util.h18
87 files changed, 727 insertions, 1370 deletions
diff --git a/lib/avatar.cpp b/lib/avatar.cpp
index c65aa25c..0573df5d 100644
--- a/lib/avatar.cpp
+++ b/lib/avatar.cpp
@@ -1,19 +1,7 @@
/******************************************************************************
- * Copyright (C) 2017 Kitsune Ral <kitsune-ral@users.sf.net>
+ * SPDX-FileCopyrightText: 2017 Kitsune Ral <kitsune-ral@users.sf.net>
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * SPDX-License-Identifier: LGPL-2.1-or-later
*/
#include "avatar.h"
@@ -37,9 +25,9 @@ public:
explicit Private(QUrl url = {}) : _url(move(url)) {}
~Private()
{
- if (isJobRunning(_thumbnailRequest))
+ if (isJobPending(_thumbnailRequest))
_thumbnailRequest->abandon();
- if (isJobRunning(_uploadRequest))
+ if (isJobPending(_uploadRequest))
_uploadRequest->abandon();
}
@@ -87,7 +75,7 @@ QImage Avatar::get(Connection* connection, int width, int height,
bool Avatar::upload(Connection* connection, const QString& fileName,
upload_callback_t callback) const
{
- if (isJobRunning(d->_uploadRequest))
+ if (isJobPending(d->_uploadRequest))
return false;
return d->upload(connection->uploadFile(fileName), move(callback));
}
@@ -95,7 +83,7 @@ bool Avatar::upload(Connection* connection, const QString& fileName,
bool Avatar::upload(Connection* connection, QIODevice* source,
upload_callback_t callback) const
{
- if (isJobRunning(d->_uploadRequest) || !source->isReadable())
+ if (isJobPending(d->_uploadRequest) || !source->isReadable())
return false;
return d->upload(connection->uploadContent(source), move(callback));
}
@@ -125,7 +113,7 @@ QImage Avatar::Private::get(Connection* connection, QSize size,
&& checkUrl(_url)) {
qCDebug(MAIN) << "Getting avatar from" << _url.toString();
_requestedSize = size;
- if (isJobRunning(_thumbnailRequest))
+ if (isJobPending(_thumbnailRequest))
_thumbnailRequest->abandon();
if (callback)
callbacks.emplace_back(move(callback));
@@ -157,7 +145,7 @@ QImage Avatar::Private::get(Connection* connection, QSize size,
bool Avatar::Private::upload(UploadContentJob* job, upload_callback_t &&callback)
{
_uploadRequest = job;
- if (!isJobRunning(_uploadRequest))
+ if (!isJobPending(_uploadRequest))
return false;
_uploadRequest->connect(_uploadRequest, &BaseJob::success, _uploadRequest,
[job, callback] { callback(job->contentUri()); });
@@ -194,7 +182,7 @@ bool Avatar::updateUrl(const QUrl& newUrl)
d->_url = newUrl;
d->_imageSource = Private::Unknown;
- if (isJobRunning(d->_thumbnailRequest))
+ if (isJobPending(d->_thumbnailRequest))
d->_thumbnailRequest->abandon();
return true;
}
diff --git a/lib/avatar.h b/lib/avatar.h
index 7a566bfa..111f565d 100644
--- a/lib/avatar.h
+++ b/lib/avatar.h
@@ -1,19 +1,7 @@
/******************************************************************************
- * Copyright (C) 2017 Kitsune Ral <kitsune-ral@users.sf.net>
+ * SPDX-FileCopyrightText: 2017 Kitsune Ral <kitsune-ral@users.sf.net>
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * SPDX-License-Identifier: LGPL-2.1-or-later
*/
#pragma once
diff --git a/lib/connection.cpp b/lib/connection.cpp
index 2a86d2eb..015e73c9 100644
--- a/lib/connection.cpp
+++ b/lib/connection.cpp
@@ -1,19 +1,7 @@
/******************************************************************************
- * Copyright (C) 2015 Felix Rohrbach <kde@fxrh.de>
+ * SPDX-FileCopyrightText: 2015 Felix Rohrbach <kde@fxrh.de>
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * SPDX-License-Identifier: LGPL-2.1-or-later
*/
#include "connection.h"
@@ -37,6 +25,7 @@
#include "csapi/versions.h"
#include "csapi/voip.h"
#include "csapi/wellknown.h"
+#include "csapi/whoami.h"
#include "events/directchatevent.h"
#include "events/eventloader.h"
@@ -133,10 +122,27 @@ public:
!= "json";
bool lazyLoading = false;
+ /** \brief Check the homeserver and resolve it if needed, before connecting
+ *
+ * A single entry for functions that need to check whether the homeserver
+ * is valid before running. May execute connectFn either synchronously
+ * or asynchronously. In case of errors, emits resolveError() if
+ * the homeserver URL is not valid and cannot be resolved from userId, or
+ * the homeserver doesn't support the requested login flow.
+ *
+ * \param userId fully-qualified MXID to resolve HS from
+ * \param connectFn a function to execute once the HS URL is good
+ * \param flow optionally, a login flow that should be supported for
+ * connectFn to work; `none`, if there's no login flow
+ * requirements
+ * \sa resolveServer, resolveError
+ */
+ void checkAndConnect(const QString &userId,
+ const std::function<void ()> &connectFn,
+ const std::optional<LoginFlow> &flow = none);
template <typename... LoginArgTs>
void loginToServer(LoginArgTs&&... loginArgs);
- void assumeIdentity(const QString& userId, const QString& accessToken,
- const QString& deviceId);
+ void completeSetup(const QString &mxId);
void removeRoom(const QString& roomId);
void consumeRoomData(SyncDataList&& roomDataList, bool fromCache);
@@ -253,7 +259,7 @@ Connection::~Connection()
void Connection::resolveServer(const QString& mxid)
{
- if (isJobRunning(d->resolverJob))
+ if (isJobPending(d->resolverJob))
d->resolverJob->abandon();
auto maybeBaseUrl = QUrl::fromUserInput(serverPart(mxid));
@@ -264,14 +270,21 @@ void Connection::resolveServer(const QString& mxid)
return;
}
- auto domain = maybeBaseUrl.host();
- qCDebug(MAIN) << "Finding the server" << domain;
+ qCDebug(MAIN) << "Finding the server" << maybeBaseUrl.host();
- d->data->setBaseUrl(maybeBaseUrl); // Just enough to check .well-known file
+ const auto& oldBaseUrl = d->data->baseUrl();
+ d->data->setBaseUrl(maybeBaseUrl); // Temporarily set it for this one call
d->resolverJob = callApi<GetWellknownJob>();
- connect(d->resolverJob, &BaseJob::finished, this, [this, maybeBaseUrl] {
- if (d->resolverJob->status() != BaseJob::NotFoundError) {
- if (d->resolverJob->status() != BaseJob::Success) {
+ // Connect to finished() to make sure baseUrl is restored in any case
+ connect(d->resolverJob, &BaseJob::finished, this, [this, maybeBaseUrl, oldBaseUrl] {
+ // Revert baseUrl so that setHomeserver() below triggers signals
+ // in case the base URL actually changed
+ d->data->setBaseUrl(oldBaseUrl);
+ if (d->resolverJob->error() == BaseJob::Abandoned)
+ return;
+
+ if (d->resolverJob->error() != BaseJob::NotFoundError) {
+ if (!d->resolverJob->status().good()) {
qCWarning(MAIN)
<< "Fetching .well-known file failed, FAIL_PROMPT";
emit resolveError(tr("Failed resolving the homeserver"));
@@ -297,12 +310,12 @@ void Connection::resolveServer(const QString& mxid)
<< "for base URL";
setHomeserver(maybeBaseUrl);
}
+ Q_ASSERT(d->loginFlowsJob != nullptr); // Ensured by setHomeserver()
connect(d->loginFlowsJob, &BaseJob::success, this,
&Connection::resolved);
connect(d->loginFlowsJob, &BaseJob::failure, this, [this] {
qCWarning(MAIN) << "Homeserver base URL sanity check failed";
- emit resolveError(
- tr("The homeserver base URL doesn't seem to work"));
+ emit resolveError(tr("The homeserver doesn't seem to be working"));
});
});
}
@@ -325,10 +338,10 @@ void Connection::loginWithPassword(const QString& userId,
const QString& initialDeviceName,
const QString& deviceId)
{
- checkAndConnect(userId, [=] {
+ d->checkAndConnect(userId, [=] {
d->loginToServer(LoginFlows::Password.type, makeUserIdentifier(userId),
password, /*token*/ "", deviceId, initialDeviceName);
- });
+ }, LoginFlows::Password);
}
SsoSession* Connection::prepareForSso(const QString& initialDeviceName,
@@ -341,17 +354,30 @@ void Connection::loginWithToken(const QByteArray& loginToken,
const QString& initialDeviceName,
const QString& deviceId)
{
+ Q_ASSERT(d->data->baseUrl().isValid() && d->loginFlows.contains(LoginFlows::Token));
d->loginToServer(LoginFlows::Token.type,
none /*user is encoded in loginToken*/, "" /*password*/,
loginToken, deviceId, initialDeviceName);
}
-void Connection::assumeIdentity(const QString& userId,
- const QString& accessToken,
+void Connection::assumeIdentity(const QString& mxId, const QString& accessToken,
const QString& deviceId)
{
- checkAndConnect(userId,
- [=] { d->assumeIdentity(userId, accessToken, deviceId); });
+ d->checkAndConnect(mxId, [this, mxId, accessToken, deviceId] {
+ d->data->setToken(accessToken.toLatin1());
+ d->data->setDeviceId(deviceId); // Can't we deduce this from access_token?
+ auto* job = callApi<GetTokenOwnerJob>();
+ connect(job, &BaseJob::success, this, [this, job, mxId] {
+ if (mxId != job->userId())
+ qCWarning(MAIN).nospace()
+ << "The access_token owner (" << job->userId()
+ << ") is different from passed MXID (" << mxId << ")!";
+ d->completeSetup(job->userId());
+ });
+ connect(job, &BaseJob::failure, this, [this, job] {
+ emit loginError(job->errorString(), job->rawDataSample());
+ });
+ });
}
void Connection::reloadCapabilities()
@@ -391,8 +417,9 @@ void Connection::Private::loginToServer(LoginArgTs&&... loginArgs)
auto loginJob =
q->callApi<LoginJob>(std::forward<LoginArgTs>(loginArgs)...);
connect(loginJob, &BaseJob::success, q, [this, loginJob] {
- assumeIdentity(loginJob->userId(), loginJob->accessToken(),
- loginJob->deviceId());
+ data->setToken(loginJob->accessToken().toLatin1());
+ data->setDeviceId(loginJob->deviceId());
+ completeSetup(loginJob->userId());
#ifndef Quotient_E2EE_ENABLED
qCWarning(E2EE) << "End-to-end encryption (E2EE) support is turned off.";
#else // Quotient_E2EE_ENABLED
@@ -405,21 +432,18 @@ void Connection::Private::loginToServer(LoginArgTs&&... loginArgs)
});
}
-void Connection::Private::assumeIdentity(const QString& userId,
- const QString& accessToken,
- const QString& deviceId)
+void Connection::Private::completeSetup(const QString& mxId)
{
- data->setUserId(userId);
+ data->setUserId(mxId);
q->user(); // Creates a User object for the local user
- data->setToken(accessToken.toLatin1());
- data->setDeviceId(deviceId);
- q->setObjectName(userId % '/' % deviceId);
+ q->setObjectName(data->userId() % '/' % data->deviceId());
qCDebug(MAIN) << "Using server" << data->baseUrl().toDisplayString()
- << "by user" << userId << "from device" << deviceId;
+ << "by user" << data->userId()
+ << "from device" << data->deviceId();
#ifndef Quotient_E2EE_ENABLED
qCWarning(E2EE) << "End-to-end encryption (E2EE) support is turned off.";
#else // Quotient_E2EE_ENABLED
- AccountSettings accountSettings(userId);
+ AccountSettings accountSettings(data->userId());
encryptionManager.reset(
new EncryptionManager(accountSettings.encryptionAccountPickle()));
if (accountSettings.encryptionAccountPickle().isEmpty()) {
@@ -432,22 +456,37 @@ void Connection::Private::assumeIdentity(const QString& userId,
q->reloadCapabilities();
}
-void Connection::checkAndConnect(const QString& userId,
- std::function<void()> connectFn)
+void Connection::Private::checkAndConnect(const QString& userId,
+ const std::function<void()>& connectFn,
+ const std::optional<LoginFlow>& flow)
{
- if (d->data->baseUrl().isValid()) {
+ if (data->baseUrl().isValid() && (!flow || loginFlows.contains(*flow))) {
connectFn();
return;
}
- // Not good to go, try to fix the homeserver URL.
+ // Not good to go, try to ascertain the homeserver URL and flows
if (userId.startsWith('@') && userId.indexOf(':') != -1) {
- connectSingleShot(this, &Connection::homeserverChanged, this, connectFn);
- // NB: doResolveServer can emit resolveError, so this is a part of
- // checkAndConnect function contract.
- resolveServer(userId);
+ q->resolveServer(userId);
+ if (flow)
+ connectSingleShot(q, &Connection::loginFlowsChanged, q,
+ [this, flow, connectFn] {
+ if (loginFlows.contains(*flow))
+ connectFn();
+ else
+ emit q->loginError(
+ tr("The homeserver at %1 does not support"
+ " the login flow '%2'")
+ .arg(data->baseUrl().toDisplayString()),
+ flow->type);
+ });
+ else
+ connectSingleShot(q, &Connection::homeserverChanged, q, connectFn);
} else
- emit resolveError(tr("%1 is an invalid homeserver URL")
- .arg(d->data->baseUrl().toString()));
+ emit q->resolveError(tr("Please provide the fully-qualified user id"
+ " (such as @user:example.org) so that the"
+ " homeserver could be resolved; the current"
+ " homeserver URL(%1) is not good")
+ .arg(data->baseUrl().toDisplayString()));
}
void Connection::logout()
@@ -932,7 +971,7 @@ void Connection::doInDirectChat(User* u,
// not left), and delete inexistent (forgotten?) ones along the way.
DirectChatsMap removals;
for (auto it = d->directChats.constFind(u);
- it != d->directChats.constEnd() && it.key() == u; ++it) {
+ it != d->directChats.cend() && it.key() == u; ++it) {
const auto& roomId = *it;
if (auto r = room(roomId, JoinState::Join)) {
Q_ASSERT(r->id() == roomId);
@@ -1178,7 +1217,7 @@ QByteArray Connection::accessToken() const
{
// The logout job needs access token to do its job; so the token is
// kept inside d->data but no more exposed to the outside world.
- return isJobRunning(d->logoutJob) ? QByteArray() : d->data->accessToken();
+ return isJobPending(d->logoutJob) ? QByteArray() : d->data->accessToken();
}
bool Connection::isLoggedIn() const { return !accessToken().isEmpty(); }
@@ -1493,12 +1532,10 @@ QByteArray Connection::generateTxnId() const
void Connection::setHomeserver(const QUrl& url)
{
- if (isJobRunning(d->resolverJob))
+ if (isJobPending(d->resolverJob))
d->resolverJob->abandon();
- d->resolverJob = nullptr;
- if (isJobRunning(d->loginFlowsJob))
+ if (isJobPending(d->loginFlowsJob))
d->loginFlowsJob->abandon();
- d->loginFlowsJob = nullptr;
d->loginFlows.clear();
if (homeserver() != url) {
@@ -1508,7 +1545,7 @@ void Connection::setHomeserver(const QUrl& url)
// Whenever a homeserver is updated, retrieve available login flows from it
d->loginFlowsJob = callApi<GetLoginFlowsJob>(BackgroundRequest);
- connect(d->loginFlowsJob, &BaseJob::finished, this, [this] {
+ connect(d->loginFlowsJob, &BaseJob::result, this, [this] {
if (d->loginFlowsJob->status().good())
d->loginFlows = d->loginFlowsJob->flows();
else
diff --git a/lib/connection.h b/lib/connection.h
index 6517b909..f3d7d725 100644
--- a/lib/connection.h
+++ b/lib/connection.h
@@ -1,19 +1,7 @@
/******************************************************************************
- * Copyright (C) 2015 Felix Rohrbach <kde@fxrh.de>
+ * SPDX-FileCopyrightText: 2015 Felix Rohrbach <kde@fxrh.de>
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * SPDX-License-Identifier: LGPL-2.1-or-later
*/
#pragma once
@@ -62,28 +50,27 @@ class SendToDeviceJob;
class SendMessageJob;
class LeaveRoomJob;
+using LoginFlow = GetLoginFlowsJob::LoginFlow;
+
+/// Predefined login flows
+struct LoginFlows {
+ static inline const LoginFlow Password { "m.login.password" };
+ static inline const LoginFlow SSO { "m.login.sso" };
+ static inline const LoginFlow Token { "m.login.token" };
+};
+
// To simplify comparisons of LoginFlows
-inline bool operator==(const GetLoginFlowsJob::LoginFlow& lhs,
- const GetLoginFlowsJob::LoginFlow& rhs)
+inline bool operator==(const LoginFlow& lhs, const LoginFlow& rhs)
{
return lhs.type == rhs.type;
}
-inline bool operator!=(const GetLoginFlowsJob::LoginFlow& lhs,
- const GetLoginFlowsJob::LoginFlow& rhs)
+inline bool operator!=(const LoginFlow& lhs, const LoginFlow& rhs)
{
return !(lhs == rhs);
}
-/// Predefined login flows
-struct LoginFlows {
- using LoginFlow = GetLoginFlowsJob::LoginFlow;
- static inline const LoginFlow Password { "m.login.password" };
- static inline const LoginFlow SSO { "m.login.sso" };
- static inline const LoginFlow Token { "m.login.token" };
-};
-
class Connection;
using room_factory_t =
@@ -497,20 +484,42 @@ public:
setUserFactory(defaultUserFactory<T>());
}
-public slots:
+public Q_SLOTS:
/** Set the homeserver base URL */
void setHomeserver(const QUrl& baseUrl);
/** Determine and set the homeserver from MXID */
void resolveServer(const QString& mxid);
+ /** \brief Log in using a username and password pair
+ *
+ * Before logging in, this method checks if the homeserver is valid and
+ * supports the password login flow. If the homeserver is invalid but
+ * a full user MXID is provided, this method calls resolveServer() using
+ * this MXID.
+ *
+ * \sa resolveServer, resolveError, loginError
+ */
void loginWithPassword(const QString& userId, const QString& password,
const QString& initialDeviceName,
const QString& deviceId = {});
+ /** \brief Log in using a login token
+ *
+ * One usual case for this method is the final stage of logging in via SSO.
+ * Unlike loginWithPassword() and assumeIdentity(), this method cannot
+ * resolve the server from the user name because the full user MXID is
+ * encoded in the login token. Callers should ensure the homeserver
+ * sanity in advance.
+ */
void loginWithToken(const QByteArray& loginToken,
const QString& initialDeviceName,
const QString& deviceId = {});
- void assumeIdentity(const QString& userId, const QString& accessToken,
+ /** \brief Use an existing access token to connect to the homeserver
+ *
+ * Similar to loginWithPassword(), this method checks that the homeserver
+ * URL is valid and tries to resolve it from the MXID in case it is not.
+ */
+ void assumeIdentity(const QString& mxId, const QString& accessToken,
const QString& deviceId);
/*! \deprecated Use loginWithPassword instead */
void connectToServer(const QString& userId, const QString& password,
@@ -656,15 +665,15 @@ public slots:
*/
virtual PostReceiptJob* postReceipt(Room* room, RoomEvent* event);
-signals:
+Q_SIGNALS:
/**
* @deprecated
* This was a signal resulting from a successful resolveServer().
* Since Connection now provides setHomeserver(), the HS URL
* may change even without resolveServer() invocation. Use
- * homeserverChanged() instead of resolved(). You can also use
- * connectToServer and connectWithToken without the HS URL set in
- * advance (i.e. without calling resolveServer), as they now trigger
+ * loginFLowsChanged() instead of resolved(). You can also use
+ * loginWith*() and assumeIdentity() without the HS URL set in
+ * advance (i.e. without calling resolveServer), as they trigger
* server name resolution from MXID if the server URL is not valid.
*/
void resolved();
@@ -853,26 +862,13 @@ protected:
*/
void onSyncSuccess(SyncData&& data, bool fromCache = false);
-protected slots:
+protected Q_SLOTS:
void syncLoopIteration();
private:
class Private;
QScopedPointer<Private> d;
- /**
- * A single entry for functions that need to check whether the
- * homeserver is valid before running. May either execute connectFn
- * synchronously or asynchronously (if tryResolve is true and
- * a DNS lookup is initiated); in case of errors, emits resolveError
- * if the homeserver URL is not valid and cannot be resolved from
- * userId.
- *
- * @param userId - fully-qualified MXID to resolve HS from
- * @param connectFn - a function to execute once the HS URL is good
- */
- void checkAndConnect(const QString& userId, std::function<void()> connectFn);
-
static room_factory_t _roomFactory;
static user_factory_t _userFactory;
};
diff --git a/lib/connectiondata.cpp b/lib/connectiondata.cpp
index d57363d0..25ab775a 100644
--- a/lib/connectiondata.cpp
+++ b/lib/connectiondata.cpp
@@ -1,19 +1,7 @@
/******************************************************************************
- * Copyright (C) 2015 Felix Rohrbach <kde@fxrh.de>
+ * SPDX-FileCopyrightText: 2015 Felix Rohrbach <kde@fxrh.de>
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * SPDX-License-Identifier: LGPL-2.1-or-later
*/
#include "connectiondata.h"
diff --git a/lib/connectiondata.h b/lib/connectiondata.h
index 000099d1..a3b2d39b 100644
--- a/lib/connectiondata.h
+++ b/lib/connectiondata.h
@@ -1,19 +1,7 @@
/******************************************************************************
- * Copyright (C) 2015 Felix Rohrbach <kde@fxrh.de>
+ * SPDX-FileCopyrightText: 2015 Felix Rohrbach <kde@fxrh.de>
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * SPDX-License-Identifier: LGPL-2.1-or-later
*/
#pragma once
diff --git a/lib/converters.cpp b/lib/converters.cpp
index e5236bb9..0df880a0 100644
--- a/lib/converters.cpp
+++ b/lib/converters.cpp
@@ -1,19 +1,7 @@
/******************************************************************************
- * Copyright (C) 2018 Kitsune Ral <kitsune-ral@users.sf.net>
+ * SPDX-FileCopyrightText: 2018 Kitsune Ral <kitsune-ral@users.sf.net>
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * SPDX-License-Identifier: LGPL-2.1-or-later
*/
#include "converters.h"
@@ -32,9 +20,9 @@ QVariant JsonConverter<QVariant>::load(const QJsonValue& jv)
return jv.toVariant();
}
-QJsonObject JsonConverter<QVariantHash>::dump(const QVariantHash& map)
+QJsonObject JsonConverter<QVariantHash>::dump(const QVariantHash& vh)
{
- return QJsonObject::fromVariantHash(map);
+ return QJsonObject::fromVariantHash(vh);
}
QVariantHash JsonConverter<QVariantHash>::load(const QJsonValue& jv)
diff --git a/lib/converters.h b/lib/converters.h
index 81d7b6d8..d4f19b60 100644
--- a/lib/converters.h
+++ b/lib/converters.h
@@ -1,19 +1,7 @@
/******************************************************************************
- * Copyright (C) 2017 Kitsune Ral <kitsune-ral@users.sf.net>
+ * SPDX-FileCopyrightText: 2017 Kitsune Ral <kitsune-ral@users.sf.net>
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * SPDX-License-Identifier: LGPL-2.1-or-later
*/
#pragma once
diff --git a/lib/e2ee.h b/lib/e2ee.h
index f49b9748..5f1857b6 100644
--- a/lib/e2ee.h
+++ b/lib/e2ee.h
@@ -1,3 +1,8 @@
+// SPDX-FileCopyrightText: 2019 Alexey Andreyev <aa13q@ya.ru>
+// SPDX-FileCopyrightText: 2019 Kitsune Ral <Kitsune-Ral@users.sf.net>
+//
+// SPDX-License-Identifier: LGPL-2.1-or-later
+
#pragma once
#include "util.h"
diff --git a/lib/encryptionmanager.cpp b/lib/encryptionmanager.cpp
index 4a1025b2..8d241eb2 100644
--- a/lib/encryptionmanager.cpp
+++ b/lib/encryptionmanager.cpp
@@ -1,3 +1,8 @@
+// SPDX-FileCopyrightText: 2019 Alexey Andreyev <aa13q@ya.ru>
+// SPDX-FileCopyrightText: 2019 Kitsune Ral <Kitsune-Ral@users.sf.net>
+//
+// SPDX-License-Identifier: LGPL-2.1-or-later
+
#ifdef Quotient_E2EE_ENABLED
#include "encryptionmanager.h"
@@ -245,7 +250,7 @@ void EncryptionManager::uploadOneTimeKeys(Connection* connection,
if (forceUpdate || d->oneTimeKeyCounts.isEmpty()) {
d->uploadOneTimeKeysInitJob = connection->callApi<UploadKeysJob>();
connect(d->uploadOneTimeKeysInitJob, &BaseJob::success, this, [this] {
- d->setOneTimeKeyCounts(d->uploadIdentityKeysJob->oneTimeKeyCounts());
+ d->setOneTimeKeyCounts(d->uploadOneTimeKeysInitJob->oneTimeKeyCounts());
});
}
diff --git a/lib/encryptionmanager.h b/lib/encryptionmanager.h
index 5df15e83..0f507337 100644
--- a/lib/encryptionmanager.h
+++ b/lib/encryptionmanager.h
@@ -1,3 +1,7 @@
+// SPDX-FileCopyrightText: 2019 Alexey Andreyev <aa13q@ya.ru>
+//
+// SPDX-License-Identifier: LGPL-2.1-or-later
+
#ifdef Quotient_E2EE_ENABLED
#pragma once
diff --git a/lib/eventitem.cpp b/lib/eventitem.cpp
index 2e2b11c0..9c47e50d 100644
--- a/lib/eventitem.cpp
+++ b/lib/eventitem.cpp
@@ -1,19 +1,7 @@
/******************************************************************************
- * Copyright (C) 2018 Kitsune Ral <kitsune-ral@users.sf.net>
+ * SPDX-FileCopyrightText: 2018 Kitsune Ral <kitsune-ral@users.sf.net>
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * SPDX-License-Identifier: LGPL-2.1-or-later
*/
#include "eventitem.h"
diff --git a/lib/eventitem.h b/lib/eventitem.h
index 7b2c3c44..2d3d9ef6 100644
--- a/lib/eventitem.h
+++ b/lib/eventitem.h
@@ -1,25 +1,14 @@
/******************************************************************************
- * Copyright (C) 2018 Kitsune Ral <kitsune-ral@users.sf.net>
+ * SPDX-FileCopyrightText: 2018 Kitsune Ral <kitsune-ral@users.sf.net>
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * SPDX-License-Identifier: LGPL-2.1-or-later
*/
#pragma once
#include "events/stateevent.h"
+#include <any>
#include <utility>
namespace Quotient {
@@ -72,6 +61,12 @@ public:
return std::exchange(evt, move(other));
}
+ /// Store arbitrary data with the event item
+ void setUserData(std::any userData) { data = userData; }
+ /// Obtain custom data previously stored with the event item
+ const std::any& userdata() const { return data; }
+ std::any& userData() { return data; }
+
protected:
template <typename EventT>
EventT* getAs()
@@ -81,6 +76,7 @@ protected:
private:
RoomEventPtr evt;
+ std::any data;
};
class TimelineItem : public EventItemBase {
diff --git a/lib/events/accountdataevents.h b/lib/events/accountdataevents.h
index 0f240aa1..d0abf577 100644
--- a/lib/events/accountdataevents.h
+++ b/lib/events/accountdataevents.h
@@ -1,19 +1,7 @@
/******************************************************************************
- * Copyright (C) 2018 Kitsune Ral <kitsune-ral@users.sf.net>
+ * SPDX-FileCopyrightText: 2018 Kitsune Ral <kitsune-ral@users.sf.net>
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * SPDX-License-Identifier: LGPL-2.1-or-later
*/
#pragma once
diff --git a/lib/events/callanswerevent.cpp b/lib/events/callanswerevent.cpp
index bf096534..f3d0a9a0 100644
--- a/lib/events/callanswerevent.cpp
+++ b/lib/events/callanswerevent.cpp
@@ -1,19 +1,7 @@
/******************************************************************************
- * Copyright (C) 2017 Marius Gripsgard <marius@ubports.com>
+ * SPDX-FileCopyrightText: 2017 Marius Gripsgard <marius@ubports.com>
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * SPDX-License-Identifier: LGPL-2.1-or-later
*/
#include "callanswerevent.h"
diff --git a/lib/events/callanswerevent.h b/lib/events/callanswerevent.h
index 2709882b..d7214468 100644
--- a/lib/events/callanswerevent.h
+++ b/lib/events/callanswerevent.h
@@ -1,19 +1,7 @@
/******************************************************************************
- * Copyright (C) 2017 Marius Gripsgard <marius@ubports.com>
+ * SPDX-FileCopyrightText: 2017 Marius Gripsgard <marius@ubports.com>
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * SPDX-License-Identifier: LGPL-2.1-or-later
*/
#pragma once
diff --git a/lib/events/callcandidatesevent.cpp b/lib/events/callcandidatesevent.cpp
index 24f0dd46..9b765064 100644
--- a/lib/events/callcandidatesevent.cpp
+++ b/lib/events/callcandidatesevent.cpp
@@ -1,19 +1,7 @@
/******************************************************************************
- * Copyright (C) 2017 Marius Gripsgard <marius@ubports.com>
+ * SPDX-FileCopyrightText: 2017 Marius Gripsgard <marius@ubports.com>
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * SPDX-License-Identifier: LGPL-2.1-or-later
*/
#include "callcandidatesevent.h"
diff --git a/lib/events/callcandidatesevent.h b/lib/events/callcandidatesevent.h
index e224f048..ae3bb150 100644
--- a/lib/events/callcandidatesevent.h
+++ b/lib/events/callcandidatesevent.h
@@ -1,19 +1,7 @@
/******************************************************************************
- * Copyright (C) 2017 Marius Gripsgard <marius@ubports.com>
+ * SPDX-FileCopyrightText: 2017 Marius Gripsgard <marius@ubports.com>
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * SPDX-License-Identifier: LGPL-2.1-or-later
*/
#pragma once
diff --git a/lib/events/callhangupevent.cpp b/lib/events/callhangupevent.cpp
index f2117f38..45b84cd4 100644
--- a/lib/events/callhangupevent.cpp
+++ b/lib/events/callhangupevent.cpp
@@ -1,19 +1,7 @@
/******************************************************************************
- * Copyright (C) 2017 Marius Gripsgard <marius@ubports.com>
+ * SPDX-FileCopyrightText: 2017 Marius Gripsgard <marius@ubports.com>
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * SPDX-License-Identifier: LGPL-2.1-or-later
*/
#include "callhangupevent.h"
diff --git a/lib/events/callhangupevent.h b/lib/events/callhangupevent.h
index 5d73fb62..432f72f5 100644
--- a/lib/events/callhangupevent.h
+++ b/lib/events/callhangupevent.h
@@ -1,19 +1,7 @@
/******************************************************************************
- * Copyright (C) 2017 Marius Gripsgard <marius@ubports.com>
+ * SPDX-FileCopyrightText: 2017 Marius Gripsgard <marius@ubports.com>
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * SPDX-License-Identifier: LGPL-2.1-or-later
*/
#pragma once
diff --git a/lib/events/callinviteevent.cpp b/lib/events/callinviteevent.cpp
index 63f331de..86478ada 100644
--- a/lib/events/callinviteevent.cpp
+++ b/lib/events/callinviteevent.cpp
@@ -1,19 +1,7 @@
/******************************************************************************
- * Copyright (C) 2017 Marius Gripsgard <marius@ubports.com>
+ * SPDX-FileCopyrightText: 2017 Marius Gripsgard <marius@ubports.com>
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * SPDX-License-Identifier: LGPL-2.1-or-later
*/
#include "callinviteevent.h"
diff --git a/lib/events/callinviteevent.h b/lib/events/callinviteevent.h
index b067a492..304c89ac 100644
--- a/lib/events/callinviteevent.h
+++ b/lib/events/callinviteevent.h
@@ -1,19 +1,7 @@
/******************************************************************************
- * Copyright (C) 2017 Marius Gripsgard <marius@ubports.com>
+ * SPDX-FileCopyrightText: 2017 Marius Gripsgard <marius@ubports.com>
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * SPDX-License-Identifier: LGPL-2.1-or-later
*/
#pragma once
diff --git a/lib/events/directchatevent.cpp b/lib/events/directchatevent.cpp
index b4027e16..39d11072 100644
--- a/lib/events/directchatevent.cpp
+++ b/lib/events/directchatevent.cpp
@@ -1,19 +1,7 @@
/******************************************************************************
- * Copyright (C) 2018 Kitsune Ral <kitsune-ral@users.sf.net>
+ * SPDX-FileCopyrightText: 2018 Kitsune Ral <kitsune-ral@users.sf.net>
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * SPDX-License-Identifier: LGPL-2.1-or-later
*/
#include "directchatevent.h"
diff --git a/lib/events/directchatevent.h b/lib/events/directchatevent.h
index bb091c5c..373e36dc 100644
--- a/lib/events/directchatevent.h
+++ b/lib/events/directchatevent.h
@@ -1,19 +1,7 @@
/******************************************************************************
- * Copyright (C) 2018 Kitsune Ral <kitsune-ral@users.sf.net>
+ * SPDX-FileCopyrightText: 2018 Kitsune Ral <kitsune-ral@users.sf.net>
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * SPDX-License-Identifier: LGPL-2.1-or-later
*/
#pragma once
diff --git a/lib/events/encryptedevent.cpp b/lib/events/encryptedevent.cpp
index 117aae37..dc9eaf2d 100644
--- a/lib/events/encryptedevent.cpp
+++ b/lib/events/encryptedevent.cpp
@@ -1,3 +1,7 @@
+// SPDX-FileCopyrightText: 2019 Alexey Andreyev <aa13q@ya.ru>
+//
+// SPDX-License-Identifier: LGPL-2.1-or-later
+
#include "encryptedevent.h"
using namespace Quotient;
diff --git a/lib/events/encryptedevent.h b/lib/events/encryptedevent.h
index 235b2aa4..9de08b00 100644
--- a/lib/events/encryptedevent.h
+++ b/lib/events/encryptedevent.h
@@ -1,3 +1,7 @@
+// SPDX-FileCopyrightText: 2019 Alexey Andreyev <aa13q@ya.ru>
+//
+// SPDX-License-Identifier: LGPL-2.1-or-later
+
#pragma once
#include "e2ee.h"
diff --git a/lib/events/encryptionevent.h b/lib/events/encryptionevent.h
index cbb6d786..3431ddd8 100644
--- a/lib/events/encryptionevent.h
+++ b/lib/events/encryptionevent.h
@@ -1,19 +1,7 @@
/******************************************************************************
- * Copyright (C) 2017 Kitsune Ral <kitsune-ral@users.sf.net>
+ * SPDX-FileCopyrightText: 2017 Kitsune Ral <kitsune-ral@users.sf.net>
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * SPDX-License-Identifier: LGPL-2.1-or-later
*/
#pragma once
diff --git a/lib/events/event.cpp b/lib/events/event.cpp
index 96e33864..97edb4e0 100644
--- a/lib/events/event.cpp
+++ b/lib/events/event.cpp
@@ -1,19 +1,7 @@
/******************************************************************************
- * Copyright (C) 2015 Felix Rohrbach <kde@fxrh.de>
+ * SPDX-FileCopyrightText: 2015 Felix Rohrbach <kde@fxrh.de>
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * SPDX-License-Identifier: LGPL-2.1-or-later
*/
#include "event.h"
@@ -61,11 +49,14 @@ QString Event::matrixType() const { return fullJson()[TypeKeyL].toString(); }
QByteArray Event::originalJson() const { return QJsonDocument(_json).toJson(); }
+// On const below: this is to catch accidental attempts to change event JSON
+// NOLINTNEXTLINE(readability-const-return-type)
const QJsonObject Event::contentJson() const
{
return fullJson()[ContentKeyL].toObject();
}
+// NOLINTNEXTLINE(readability-const-return-type)
const QJsonObject Event::unsignedJson() const
{
return fullJson()[UnsignedKeyL].toObject();
diff --git a/lib/events/event.h b/lib/events/event.h
index 626a0229..c5752a7a 100644
--- a/lib/events/event.h
+++ b/lib/events/event.h
@@ -1,19 +1,7 @@
/******************************************************************************
- * Copyright (C) 2015 Felix Rohrbach <kde@fxrh.de>
+ * SPDX-FileCopyrightText: 2015 Felix Rohrbach <kde@fxrh.de>
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * SPDX-License-Identifier: LGPL-2.1-or-later
*/
#pragma once
@@ -298,7 +286,7 @@ using Events = EventsArray<Event>;
// === is<>(), eventCast<>() and visit<>() ===
-template <typename EventT>
+template <class EventT>
inline bool is(const Event& e)
{
return e.type() == typeId<EventT>();
@@ -309,7 +297,7 @@ inline bool isUnknown(const Event& e)
return e.type() == unknownEventTypeId();
}
-template <typename EventT, typename BasePtrT>
+template <class EventT, typename BasePtrT>
inline auto eventCast(const BasePtrT& eptr)
-> decltype(static_cast<EventT*>(&*eptr))
{
@@ -319,7 +307,7 @@ inline auto eventCast(const BasePtrT& eptr)
}
// A single generic catch-all visitor
-template <typename BaseEventT, typename FnT>
+template <class BaseEventT, typename FnT>
inline auto visit(const BaseEventT& event, FnT&& visitor)
-> decltype(visitor(event))
{
@@ -327,18 +315,18 @@ inline auto visit(const BaseEventT& event, FnT&& visitor)
}
namespace _impl {
- template <typename T, typename FnT>
- constexpr auto needs_downcast()
- {
- return !std::is_convertible_v<T, fn_arg_t<FnT>>;
- }
+ // Using bool instead of auto below because auto apparently upsets MSVC
+ template <class BaseT, typename FnT>
+ inline constexpr bool needs_downcast =
+ std::is_base_of_v<BaseT, std::decay_t<fn_arg_t<FnT>>>
+ && !std::is_same_v<BaseT, std::decay_t<fn_arg_t<FnT>>>;
}
// A single type-specific void visitor
-template <typename BaseEventT, typename FnT>
-inline std::enable_if_t<_impl::needs_downcast<BaseEventT, FnT>()
+template <class BaseT, typename FnT>
+inline auto visit(const BaseT& event, FnT&& visitor)
+ -> std::enable_if_t<_impl::needs_downcast<BaseT, FnT>
&& std::is_void_v<fn_return_t<FnT>>>
-visit(const BaseEventT& event, FnT&& visitor)
{
using event_type = fn_arg_t<FnT>;
if (is<std::decay_t<event_type>>(event))
@@ -347,10 +335,10 @@ visit(const BaseEventT& event, FnT&& visitor)
// A single type-specific non-void visitor with an optional default value
// non-voidness is guarded by defaultValue type
-template <typename BaseEventT, typename FnT>
-inline std::enable_if_t<_impl::needs_downcast<BaseEventT, FnT>(), fn_return_t<FnT>>
-visit(const BaseEventT& event, FnT&& visitor,
- fn_return_t<FnT>&& defaultValue = {})
+template <class BaseT, typename FnT>
+inline auto visit(const BaseT& event, FnT&& visitor,
+ fn_return_t<FnT>&& defaultValue = {})
+ -> std::enable_if_t<_impl::needs_downcast<BaseT, FnT>, fn_return_t<FnT>>
{
using event_type = fn_arg_t<FnT>;
if (is<std::decay_t<event_type>>(event))
@@ -359,9 +347,10 @@ visit(const BaseEventT& event, FnT&& visitor,
}
// A chain of 2 or more visitors
-template <typename BaseEventT, typename FnT1, typename FnT2, typename... FnTs>
-inline fn_return_t<FnT1> visit(const BaseEventT& event, FnT1&& visitor1,
- FnT2&& visitor2, FnTs&&... visitors)
+template <class BaseT, typename FnT1, typename FnT2, typename... FnTs>
+inline std::common_type_t<fn_return_t<FnT1>, fn_return_t<FnT2>> visit(
+ const BaseT& event, FnT1&& visitor1, FnT2&& visitor2,
+ FnTs&&... visitors)
{
using event_type1 = fn_arg_t<FnT1>;
if (is<std::decay_t<event_type1>>(event))
@@ -374,8 +363,8 @@ inline fn_return_t<FnT1> visit(const BaseEventT& event, FnT1&& visitor1,
// over a range of event pointers
template <typename RangeT, typename... FnTs>
inline auto visitEach(RangeT&& events, FnTs&&... visitors)
- -> std::enable_if_t<std::is_convertible_v<
- std::decay_t<decltype(**events.begin())>, Event>>
+ -> std::enable_if_t<std::is_void_v<
+ decltype(visit(**begin(events), std::forward<FnTs>(visitors)...))>>
{
for (auto&& evtPtr: events)
visit(*evtPtr, std::forward<FnTs>(visitors)...);
diff --git a/lib/events/eventcontent.cpp b/lib/events/eventcontent.cpp
index 0cb9e292..18b1b94b 100644
--- a/lib/events/eventcontent.cpp
+++ b/lib/events/eventcontent.cpp
@@ -1,19 +1,7 @@
/******************************************************************************
- * Copyright (C) 2017 Kitsune Ral <kitsune-ral@users.sf.net>
+ * SPDX-FileCopyrightText: 2017 Kitsune Ral <kitsune-ral@users.sf.net>
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * SPDX-License-Identifier: LGPL-2.1-or-later
*/
#include "eventcontent.h"
diff --git a/lib/events/eventcontent.h b/lib/events/eventcontent.h
index 9c167d4b..e247adbf 100644
--- a/lib/events/eventcontent.h
+++ b/lib/events/eventcontent.h
@@ -1,19 +1,7 @@
/******************************************************************************
- * Copyright (C) 2017 Kitsune Ral <kitsune-ral@users.sf.net>
+ * SPDX-FileCopyrightText: 2017 Kitsune Ral <kitsune-ral@users.sf.net>
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * SPDX-License-Identifier: LGPL-2.1-or-later
*/
#pragma once
diff --git a/lib/events/eventloader.h b/lib/events/eventloader.h
index ebb96441..0d95daf5 100644
--- a/lib/events/eventloader.h
+++ b/lib/events/eventloader.h
@@ -1,19 +1,7 @@
/******************************************************************************
- * Copyright (C) 2018 Kitsune Ral <kitsune-ral@users.sf.net>
+ * SPDX-FileCopyrightText: 2018 Kitsune Ral <kitsune-ral@users.sf.net>
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * SPDX-License-Identifier: LGPL-2.1-or-later
*/
#pragma once
diff --git a/lib/events/reactionevent.cpp b/lib/events/reactionevent.cpp
index 003c8ead..9b43e372 100644
--- a/lib/events/reactionevent.cpp
+++ b/lib/events/reactionevent.cpp
@@ -1,19 +1,7 @@
/******************************************************************************
- * Copyright (C) 2019 Kitsune Ral <kitsune-ral@users.sf.net>
+ * SPDX-FileCopyrightText: 2019 Kitsune Ral <kitsune-ral@users.sf.net>
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * SPDX-License-Identifier: LGPL-2.1-or-later
*/
#include "reactionevent.h"
diff --git a/lib/events/reactionevent.h b/lib/events/reactionevent.h
index 48b0bc6c..09166b24 100644
--- a/lib/events/reactionevent.h
+++ b/lib/events/reactionevent.h
@@ -1,19 +1,7 @@
/******************************************************************************
- * Copyright (C) 2019 Kitsune Ral <kitsune-ral@users.sf.net>
+ * SPDX-FileCopyrightText: 2019 Kitsune Ral <kitsune-ral@users.sf.net>
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * SPDX-License-Identifier: LGPL-2.1-or-later
*/
#pragma once
diff --git a/lib/events/receiptevent.cpp b/lib/events/receiptevent.cpp
index deb3c4e8..b6f0fcdd 100644
--- a/lib/events/receiptevent.cpp
+++ b/lib/events/receiptevent.cpp
@@ -1,19 +1,7 @@
/******************************************************************************
- * Copyright (C) 2016 Felix Rohrbach <kde@fxrh.de>
+ * SPDX-FileCopyrightText: 2016 Felix Rohrbach <kde@fxrh.de>
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * SPDX-License-Identifier: LGPL-2.1-or-later
*/
/*
diff --git a/lib/events/receiptevent.h b/lib/events/receiptevent.h
index b7adea44..ec297a6c 100644
--- a/lib/events/receiptevent.h
+++ b/lib/events/receiptevent.h
@@ -1,19 +1,7 @@
/******************************************************************************
- * Copyright (C) 2016 Felix Rohrbach <kde@fxrh.de>
+ * SPDX-FileCopyrightText: 2016 Felix Rohrbach <kde@fxrh.de>
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * SPDX-License-Identifier: LGPL-2.1-or-later
*/
#pragma once
diff --git a/lib/events/redactionevent.cpp b/lib/events/redactionevent.cpp
index bf467718..5889773c 100644
--- a/lib/events/redactionevent.cpp
+++ b/lib/events/redactionevent.cpp
@@ -1 +1,5 @@
+// SPDX-FileCopyrightText: 2019 Kitsune Ral <Kitsune-Ral@users.sf.net>
+//
+// SPDX-License-Identifier: CC0-1.0
+
#include "redactionevent.h"
diff --git a/lib/events/redactionevent.h b/lib/events/redactionevent.h
index 3b3af18e..320db6f2 100644
--- a/lib/events/redactionevent.h
+++ b/lib/events/redactionevent.h
@@ -1,19 +1,7 @@
/******************************************************************************
- * Copyright (C) 2017 Kitsune Ral <kitsune-ral@users.sf.net>
+ * SPDX-FileCopyrightText: 2017 Kitsune Ral <kitsune-ral@users.sf.net>
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * SPDX-License-Identifier: LGPL-2.1-or-later
*/
#pragma once
diff --git a/lib/events/roomavatarevent.h b/lib/events/roomavatarevent.h
index c2100eaa..649412e8 100644
--- a/lib/events/roomavatarevent.h
+++ b/lib/events/roomavatarevent.h
@@ -1,19 +1,7 @@
/******************************************************************************
- * Copyright (C) 2017 Kitsune Ral <kitsune-ral@users.sf.net>
+ * SPDX-FileCopyrightText: 2017 Kitsune Ral <kitsune-ral@users.sf.net>
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * SPDX-License-Identifier: LGPL-2.1-or-later
*/
#pragma once
diff --git a/lib/events/roomcanonicalaliasevent.h b/lib/events/roomcanonicalaliasevent.h
index 4a21b7cc..eda94d2d 100644
--- a/lib/events/roomcanonicalaliasevent.h
+++ b/lib/events/roomcanonicalaliasevent.h
@@ -1,19 +1,7 @@
/******************************************************************************
- * Copyright (C) 2020 QMatrixClient project
+ * SPDX-FileCopyrightText: 2020 QMatrixClient project
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * SPDX-License-Identifier: LGPL-2.1-or-later
*/
#pragma once
diff --git a/lib/events/roomcreateevent.cpp b/lib/events/roomcreateevent.cpp
index 0fc7d6b9..3d9ec4a3 100644
--- a/lib/events/roomcreateevent.cpp
+++ b/lib/events/roomcreateevent.cpp
@@ -1,19 +1,7 @@
/******************************************************************************
- * Copyright (C) 2019 QMatrixClient project
+ * SPDX-FileCopyrightText: 2019 QMatrixClient project
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * SPDX-License-Identifier: LGPL-2.1-or-later
*/
#include "roomcreateevent.h"
diff --git a/lib/events/roomcreateevent.h b/lib/events/roomcreateevent.h
index 91aefe9e..8328d38a 100644
--- a/lib/events/roomcreateevent.h
+++ b/lib/events/roomcreateevent.h
@@ -1,19 +1,7 @@
/******************************************************************************
- * Copyright (C) 2019 QMatrixClient project
+ * SPDX-FileCopyrightText: 2019 QMatrixClient project
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * SPDX-License-Identifier: LGPL-2.1-or-later
*/
#pragma once
diff --git a/lib/events/roomevent.cpp b/lib/events/roomevent.cpp
index a2dbc07d..2b6ac2be 100644
--- a/lib/events/roomevent.cpp
+++ b/lib/events/roomevent.cpp
@@ -1,19 +1,7 @@
/******************************************************************************
- * Copyright (C) 2018 Kitsune Ral <kitsune-ral@users.sf.net>
+ * SPDX-FileCopyrightText: 2018 Kitsune Ral <kitsune-ral@users.sf.net>
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * SPDX-License-Identifier: LGPL-2.1-or-later
*/
#include "roomevent.h"
diff --git a/lib/events/roomevent.h b/lib/events/roomevent.h
index 084cb524..3fafecfd 100644
--- a/lib/events/roomevent.h
+++ b/lib/events/roomevent.h
@@ -1,19 +1,7 @@
/******************************************************************************
- * Copyright (C) 2018 Kitsune Ral <kitsune-ral@users.sf.net>
+ * SPDX-FileCopyrightText: 2018 Kitsune Ral <kitsune-ral@users.sf.net>
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * SPDX-License-Identifier: LGPL-2.1-or-later
*/
#pragma once
diff --git a/lib/events/roommemberevent.cpp b/lib/events/roommemberevent.cpp
index 913bde74..d093286c 100644
--- a/lib/events/roommemberevent.cpp
+++ b/lib/events/roommemberevent.cpp
@@ -1,19 +1,7 @@
/******************************************************************************
- * Copyright (C) 2015 Felix Rohrbach <kde@fxrh.de>
+ * SPDX-FileCopyrightText: 2015 Felix Rohrbach <kde@fxrh.de>
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * SPDX-License-Identifier: LGPL-2.1-or-later
*/
#include "roommemberevent.h"
diff --git a/lib/events/roommemberevent.h b/lib/events/roommemberevent.h
index cebaaf10..b7a7c9df 100644
--- a/lib/events/roommemberevent.h
+++ b/lib/events/roommemberevent.h
@@ -1,19 +1,7 @@
/******************************************************************************
- * Copyright (C) 2015 Felix Rohrbach <kde@fxrh.de>
+ * SPDX-FileCopyrightText: 2015 Felix Rohrbach <kde@fxrh.de>
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * SPDX-License-Identifier: LGPL-2.1-or-later
*/
#pragma once
diff --git a/lib/events/roommessageevent.cpp b/lib/events/roommessageevent.cpp
index 616a034f..19d460b8 100644
--- a/lib/events/roommessageevent.cpp
+++ b/lib/events/roommessageevent.cpp
@@ -1,19 +1,7 @@
/******************************************************************************
- * Copyright (C) 2015 Felix Rohrbach <kde@fxrh.de>
+ * SPDX-FileCopyrightText: 2015 Felix Rohrbach <kde@fxrh.de>
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * SPDX-License-Identifier: LGPL-2.1-or-later
*/
#include "roommessageevent.h"
diff --git a/lib/events/roommessageevent.h b/lib/events/roommessageevent.h
index 2501d097..ebc9d564 100644
--- a/lib/events/roommessageevent.h
+++ b/lib/events/roommessageevent.h
@@ -1,19 +1,7 @@
/******************************************************************************
- * Copyright (C) 2015 Felix Rohrbach <kde@fxrh.de>
+ * SPDX-FileCopyrightText: 2015 Felix Rohrbach <kde@fxrh.de>
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * SPDX-License-Identifier: LGPL-2.1-or-later
*/
#pragma once
diff --git a/lib/events/roomtombstoneevent.cpp b/lib/events/roomtombstoneevent.cpp
index f93eb60d..163e1d3a 100644
--- a/lib/events/roomtombstoneevent.cpp
+++ b/lib/events/roomtombstoneevent.cpp
@@ -1,19 +1,7 @@
/******************************************************************************
- * Copyright (C) 2019 QMatrixClient project
+ * SPDX-FileCopyrightText: 2019 QMatrixClient project
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * SPDX-License-Identifier: LGPL-2.1-or-later
*/
#include "roomtombstoneevent.h"
diff --git a/lib/events/roomtombstoneevent.h b/lib/events/roomtombstoneevent.h
index 2c2f0663..8d50aba0 100644
--- a/lib/events/roomtombstoneevent.h
+++ b/lib/events/roomtombstoneevent.h
@@ -1,19 +1,7 @@
/******************************************************************************
- * Copyright (C) 2019 QMatrixClient project
+ * SPDX-FileCopyrightText: 2019 QMatrixClient project
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * SPDX-License-Identifier: LGPL-2.1-or-later
*/
#pragma once
diff --git a/lib/events/simplestateevents.h b/lib/events/simplestateevents.h
index cde5b0fd..58ba3b5a 100644
--- a/lib/events/simplestateevents.h
+++ b/lib/events/simplestateevents.h
@@ -1,19 +1,7 @@
/******************************************************************************
- * Copyright (C) 2017 Kitsune Ral <kitsune-ral@users.sf.net>
+ * SPDX-FileCopyrightText: 2017 Kitsune Ral <kitsune-ral@users.sf.net>
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * SPDX-License-Identifier: LGPL-2.1-or-later
*/
#pragma once
diff --git a/lib/events/stateevent.cpp b/lib/events/stateevent.cpp
index 5909e8a6..7bde12bb 100644
--- a/lib/events/stateevent.cpp
+++ b/lib/events/stateevent.cpp
@@ -1,19 +1,7 @@
/******************************************************************************
- * Copyright (C) 2018 Kitsune Ral <kitsune-ral@users.sf.net>
+ * SPDX-FileCopyrightText: 2018 Kitsune Ral <kitsune-ral@users.sf.net>
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * SPDX-License-Identifier: LGPL-2.1-or-later
*/
#include "stateevent.h"
diff --git a/lib/events/stateevent.h b/lib/events/stateevent.h
index 20a85f83..0db37767 100644
--- a/lib/events/stateevent.h
+++ b/lib/events/stateevent.h
@@ -1,19 +1,7 @@
/******************************************************************************
- * Copyright (C) 2018 Kitsune Ral <kitsune-ral@users.sf.net>
+ * SPDX-FileCopyrightText: 2018 Kitsune Ral <kitsune-ral@users.sf.net>
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * SPDX-License-Identifier: LGPL-2.1-or-later
*/
#pragma once
diff --git a/lib/events/stickerevent.cpp b/lib/events/stickerevent.cpp
new file mode 100644
index 00000000..ea4dff3f
--- /dev/null
+++ b/lib/events/stickerevent.cpp
@@ -0,0 +1,26 @@
+// SDPX-FileCopyrightText: 2020 Carl Schwan <carlschwan@kde.org>
+// SPDX-License-Identifier: LGPL-2.1-or-later
+
+#include "stickerevent.h"
+
+using namespace Quotient;
+
+StickerEvent::StickerEvent(const QJsonObject &obj)
+ : RoomEvent(typeId(), obj)
+ , m_imageContent(EventContent::ImageContent(obj["content"_ls].toObject()))
+{}
+
+QString StickerEvent::body() const
+{
+ return content<QString>("body"_ls);
+}
+
+const EventContent::ImageContent &StickerEvent::image() const
+{
+ return m_imageContent;
+}
+
+QUrl StickerEvent::url() const
+{
+ return m_imageContent.url;
+}
diff --git a/lib/events/stickerevent.h b/lib/events/stickerevent.h
new file mode 100644
index 00000000..93671086
--- /dev/null
+++ b/lib/events/stickerevent.h
@@ -0,0 +1,38 @@
+// SDPX-FileCopyrightText: 2020 Carl Schwan <carlschwan@kde.org>
+// SPDX-License-Identifier: LGPL-2.1-or-later
+
+#pragma once
+
+#include "roomevent.h"
+#include "eventcontent.h"
+
+namespace Quotient {
+
+/// Sticker messages are specialised image messages that are displayed without
+/// controls (e.g. no "download" link, or light-box view on click, as would be
+/// displayed for for m.image events).
+class StickerEvent : public RoomEvent
+{
+public:
+ DEFINE_EVENT_TYPEID("m.sticker", StickerEvent)
+
+ explicit StickerEvent(const QJsonObject &obj);
+
+ /// \brief A textual representation or associated description of the
+ /// sticker image.
+ ///
+ /// This could be the alt text of the original image, or a message to
+ /// accompany and further describe the sticker.
+ QString body() const;
+
+ /// \brief Metadata about the image referred to in url including a
+ /// thumbnail representation.
+ const EventContent::ImageContent &image() const;
+
+ /// \brief The URL to the sticker image. This must be a valid mxc:// URI.
+ QUrl url() const;
+private:
+ EventContent::ImageContent m_imageContent;
+};
+REGISTER_EVENT_TYPE(StickerEvent)
+} // namespace Quotient
diff --git a/lib/events/typingevent.cpp b/lib/events/typingevent.cpp
index e102fc79..7d3f71e5 100644
--- a/lib/events/typingevent.cpp
+++ b/lib/events/typingevent.cpp
@@ -1,19 +1,7 @@
/******************************************************************************
- * Copyright (C) 2015 Felix Rohrbach <kde@fxrh.de>
+ * SPDX-FileCopyrightText: 2015 Felix Rohrbach <kde@fxrh.de>
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * SPDX-License-Identifier: LGPL-2.1-or-later
*/
#include "typingevent.h"
diff --git a/lib/events/typingevent.h b/lib/events/typingevent.h
index 97e1f9cc..8ca4f8e4 100644
--- a/lib/events/typingevent.h
+++ b/lib/events/typingevent.h
@@ -1,19 +1,7 @@
/******************************************************************************
- * Copyright (C) 2015 Felix Rohrbach <kde@fxrh.de>
+ * SPDX-FileCopyrightText: 2015 Felix Rohrbach <kde@fxrh.de>
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * SPDX-License-Identifier: LGPL-2.1-or-later
*/
#pragma once
diff --git a/lib/jobs/basejob.cpp b/lib/jobs/basejob.cpp
index 422931ee..a0c88581 100644
--- a/lib/jobs/basejob.cpp
+++ b/lib/jobs/basejob.cpp
@@ -1,19 +1,7 @@
/******************************************************************************
- * Copyright (C) 2015 Felix Rohrbach <kde@fxrh.de>
+ * SPDX-FileCopyrightText: 2015 Felix Rohrbach <kde@fxrh.de>
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * SPDX-License-Identifier: LGPL-2.1-or-later
*/
#include "basejob.h"
@@ -24,6 +12,7 @@
#include <QtCore/QTimer>
#include <QtCore/QStringBuilder>
#include <QtCore/QMetaEnum>
+#include <QtCore/QPointer>
#include <QtNetwork/QNetworkAccessManager>
#include <QtNetwork/QNetworkReply>
#include <QtNetwork/QNetworkRequest>
@@ -76,15 +65,6 @@ QDebug BaseJob::Status::dumpToLog(QDebug dbg) const
return dbg << ": " << message;
}
-struct NetworkReplyDeleter : public QScopedPointerDeleteLater {
- static inline void cleanup(QNetworkReply* reply)
- {
- if (reply && reply->isRunning())
- reply->abort();
- QScopedPointerDeleteLater::cleanup(reply);
- }
-};
-
template <typename... Ts>
constexpr auto make_array(Ts&&... items)
{
@@ -112,6 +92,16 @@ public:
retryTimer.setSingleShot(true);
}
+ ~Private()
+ {
+ if (reply) {
+ if (reply->isRunning()) {
+ reply->abort();
+ }
+ delete reply;
+ }
+ }
+
void sendRequest();
/*! \brief Parse the response byte array into JSON
*
@@ -140,7 +130,10 @@ public:
QByteArrayList expectedKeys;
- QScopedPointer<QNetworkReply, NetworkReplyDeleter> reply;
+ // When the QNetworkAccessManager is destroyed it destroys all pending replies.
+ // Using QPointer allows us to know when that happend.
+ QPointer<QNetworkReply> reply;
+
Status status = Unprepared;
QByteArray rawResponse;
/// Contains a null document in case of non-JSON body (for a successful
@@ -194,6 +187,7 @@ BaseJob::BaseJob(HttpVerb verb, const QString& name, const QString& endpoint,
setObjectName(name);
connect(&d->timer, &QTimer::timeout, this, &BaseJob::timeout);
connect(&d->retryTimer, &QTimer::timeout, this, [this] {
+ qCDebug(d->logCat) << "Retrying" << this;
d->connection->submit(this);
});
}
@@ -258,7 +252,7 @@ void BaseJob::setExpectedContentTypes(const QByteArrayList& contentTypes)
d->expectedContentTypes = contentTypes;
}
-const QByteArrayList BaseJob::expectedKeys() const { return d->expectedKeys; }
+QByteArrayList BaseJob::expectedKeys() const { return d->expectedKeys; }
void BaseJob::addExpectedKey(const QByteArray& key) { d->expectedKeys << key; }
@@ -315,16 +309,16 @@ void BaseJob::Private::sendRequest()
switch (verb) {
case HttpVerb::Get:
- reply.reset(connection->nam()->get(req));
+ reply = connection->nam()->get(req);
break;
case HttpVerb::Post:
- reply.reset(connection->nam()->post(req, requestData.source()));
+ reply = connection->nam()->post(req, requestData.source());
break;
case HttpVerb::Put:
- reply.reset(connection->nam()->put(req, requestData.source()));
+ reply = connection->nam()->put(req, requestData.source());
break;
case HttpVerb::Delete:
- reply.reset(connection->nam()->deleteResource(req));
+ reply = connection->nam()->sendCustomRequest(req, "DELETE", requestData.source());
break;
}
}
@@ -337,7 +331,7 @@ void BaseJob::beforeAbandon() { }
void BaseJob::initiate(ConnectionData* connData, bool inBackground)
{
- if (connData && connData->baseUrl().isValid()) {
+ if (Q_LIKELY(connData && connData->baseUrl().isValid())) {
d->inBackground = inBackground;
d->connection = connData;
doPrepare();
@@ -350,7 +344,7 @@ void BaseJob::initiate(ConnectionData* connData, bool inBackground)
setStatus(FileError, "Request data not ready");
}
Q_ASSERT(status().code != Pending); // doPrepare() must NOT set this
- if (status().code == Unprepared) {
+ if (Q_LIKELY(status().code == Unprepared)) {
d->connection->submit(this);
return;
}
@@ -369,8 +363,11 @@ void BaseJob::initiate(ConnectionData* connData, bool inBackground)
void BaseJob::sendRequest()
{
- if (status().code == Abandoned)
+ if (status().code == Abandoned) {
+ qCDebug(d->logCat) << "Won't proceed with the abandoned request:"
+ << d->dumpRequest();
return;
+ }
Q_ASSERT(d->connection && status().code == Pending);
qCDebug(d->logCat).noquote() << "Making" << d->dumpRequest();
d->needsToken |= d->connection->needsToken(objectName());
@@ -510,14 +507,15 @@ BaseJob::Status BaseJob::prepareResult() { return Success; }
BaseJob::Status BaseJob::prepareError()
{
- if (!d->rawResponse.isEmpty()) {
- if (const auto status = d->parseJson(); !status.good())
- return status; // If there's anything there, it should be JSON
- if (d->jsonResponse.isArray()) // ...specifically, a JSON object
- return { IncorrectResponse,
- tr("Malformed error JSON: an array instead of an object") };
- }
+ // Try to make sense of the error payload but be prepared for all kinds
+ // of unexpected stuff (raw HTML, plain text, foreign JSON among those)
+ if (!d->rawResponse.isEmpty()
+ && reply()->rawHeader("Content-Type") == "application/json")
+ d->parseJson();
+ // By now, if d->parseJson() above succeeded then jsonData() will return
+ // a valid JSON object - or an empty object otherwise (in which case most
+ // of if's below will fall through to `return NoError` at the end
const auto& errorJson = jsonData();
const auto errCode = errorJson.value("errcode"_ls).toString();
if (error() == TooManyRequestsError || errCode == "M_LIMIT_EXCEEDED") {
@@ -615,10 +613,12 @@ void BaseJob::finishJob()
qCWarning(d->logCat).nospace()
<< this << ": retry #" << d->retriesTaken << " in "
<< retryIn.count() << " s";
+ setStatus(Pending, "Pending retry");
d->retryTimer.start(retryIn);
emit retryScheduled(d->retriesTaken, milliseconds(retryIn).count());
return;
}
+ [[fallthrough]];
default:;
}
diff --git a/lib/jobs/basejob.h b/lib/jobs/basejob.h
index be2926be..3165edd3 100644
--- a/lib/jobs/basejob.h
+++ b/lib/jobs/basejob.h
@@ -1,19 +1,7 @@
/******************************************************************************
- * Copyright (C) 2015 Felix Rohrbach <kde@fxrh.de>
+ * SPDX-FileCopyrightText: 2015 Felix Rohrbach <kde@fxrh.de>
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * SPDX-License-Identifier: LGPL-2.1-or-later
*/
#pragma once
@@ -136,6 +124,14 @@ public:
{
return !operator==(other);
}
+ bool operator==(int otherCode) const
+ {
+ return code == otherCode;
+ }
+ bool operator!=(int otherCode) const
+ {
+ return !operator==(otherCode);
+ }
int code;
QString message;
@@ -251,7 +247,7 @@ public:
return dbg << j->objectName();
}
-public slots:
+public Q_SLOTS:
void initiate(ConnectionData* connData, bool inBackground);
/**
@@ -263,7 +259,7 @@ public slots:
*/
void abandon();
-signals:
+Q_SIGNALS:
/** The job is about to send a network request */
void aboutToSendRequest();
@@ -355,7 +351,7 @@ protected:
const QByteArrayList& expectedContentTypes() const;
void addExpectedContentType(const QByteArray& contentType);
void setExpectedContentTypes(const QByteArrayList& contentTypes);
- const QByteArrayList expectedKeys() const;
+ QByteArrayList expectedKeys() const;
void addExpectedKey(const QByteArray &key);
void setExpectedKeys(const QByteArrayList &keys);
@@ -433,7 +429,7 @@ protected:
// Job objects should only be deleted via QObject::deleteLater
~BaseJob() override;
-protected slots:
+protected Q_SLOTS:
void timeout();
/*! \brief Check the pending or received reply for upfront issues
@@ -456,7 +452,7 @@ protected slots:
*/
virtual Status checkReply(const QNetworkReply *reply) const;
-private slots:
+private Q_SLOTS:
void sendRequest();
void gotReply();
@@ -470,7 +466,7 @@ private:
QScopedPointer<Private> d;
};
-inline bool isJobRunning(BaseJob* job)
+inline bool isJobPending(BaseJob* job)
{
return job && job->error() == BaseJob::Pending;
}
diff --git a/lib/jobs/downloadfilejob.cpp b/lib/jobs/downloadfilejob.cpp
index 7b4cf690..0011a97c 100644
--- a/lib/jobs/downloadfilejob.cpp
+++ b/lib/jobs/downloadfilejob.cpp
@@ -64,7 +64,7 @@ void DownloadFileJob::onSentRequest(QNetworkReply* reply)
return;
auto sizeHeader = reply->header(QNetworkRequest::ContentLengthHeader);
if (sizeHeader.isValid()) {
- auto targetSize = sizeHeader.value<qint64>();
+ auto targetSize = sizeHeader.toLongLong();
if (targetSize != -1)
if (!d->tempFile->resize(targetSize)) {
qCWarning(JOBS) << "Failed to allocate" << targetSize
diff --git a/lib/jobs/mediathumbnailjob.cpp b/lib/jobs/mediathumbnailjob.cpp
index a69f00e9..fbea8797 100644
--- a/lib/jobs/mediathumbnailjob.cpp
+++ b/lib/jobs/mediathumbnailjob.cpp
@@ -1,19 +1,7 @@
/******************************************************************************
- * Copyright (C) 2016 Felix Rohrbach <kde@fxrh.de>
+ * SPDX-FileCopyrightText: 2016 Felix Rohrbach <kde@fxrh.de>
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * SPDX-License-Identifier: LGPL-2.1-or-later
*/
#include "mediathumbnailjob.h"
diff --git a/lib/jobs/mediathumbnailjob.h b/lib/jobs/mediathumbnailjob.h
index e6d39085..cb55a0b0 100644
--- a/lib/jobs/mediathumbnailjob.h
+++ b/lib/jobs/mediathumbnailjob.h
@@ -1,19 +1,7 @@
/******************************************************************************
- * Copyright (C) 2016 Felix Rohrbach <kde@fxrh.de>
+ * SPDX-FileCopyrightText: 2016 Felix Rohrbach <kde@fxrh.de>
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * SPDX-License-Identifier: LGPL-2.1-or-later
*/
#pragma once
diff --git a/lib/jobs/postreadmarkersjob.h b/lib/jobs/postreadmarkersjob.h
deleted file mode 100644
index 5a4d942c..00000000
--- a/lib/jobs/postreadmarkersjob.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/******************************************************************************
- * Copyright (C) 2017 Kitsune Ral <kitsune-ral@users.sf.net>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#pragma once
-
-#include "basejob.h"
-
-#include <QtCore/QJsonObject>
-
-using namespace Quotient;
-
-class PostReadMarkersJob : public BaseJob {
-public:
- explicit PostReadMarkersJob(const QString& roomId,
- const QString& readUpToEventId)
- : BaseJob(
- HttpVerb::Post, "PostReadMarkersJob",
- QStringLiteral("_matrix/client/r0/rooms/%1/read_markers").arg(roomId))
- {
- setRequestData(
- QJsonObject { { QStringLiteral("m.fully_read"), readUpToEventId } });
- }
-};
diff --git a/lib/jobs/requestdata.h b/lib/jobs/requestdata.h
index 9cb5ecaf..2a227646 100644
--- a/lib/jobs/requestdata.h
+++ b/lib/jobs/requestdata.h
@@ -1,19 +1,7 @@
/******************************************************************************
- * Copyright (C) 2018 Kitsune Ral <kitsune-ral@users.sf.net>
+ * SPDX-FileCopyrightText: 2018 Kitsune Ral <kitsune-ral@users.sf.net>
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * SPDX-License-Identifier: LGPL-2.1-or-later
*/
#pragma once
diff --git a/lib/jobs/syncjob.cpp b/lib/jobs/syncjob.cpp
index 9087fe50..beb0a535 100644
--- a/lib/jobs/syncjob.cpp
+++ b/lib/jobs/syncjob.cpp
@@ -1,19 +1,7 @@
/******************************************************************************
- * Copyright (C) 2016 Felix Rohrbach <kde@fxrh.de>
+ * SPDX-FileCopyrightText: 2016 Felix Rohrbach <kde@fxrh.de>
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * SPDX-License-Identifier: LGPL-2.1-or-later
*/
#include "syncjob.h"
diff --git a/lib/jobs/syncjob.h b/lib/jobs/syncjob.h
index bf139a7b..a7d10ed8 100644
--- a/lib/jobs/syncjob.h
+++ b/lib/jobs/syncjob.h
@@ -1,19 +1,7 @@
/******************************************************************************
- * Copyright (C) 2016 Felix Rohrbach <kde@fxrh.de>
+ * SPDX-FileCopyrightText: 2016 Felix Rohrbach <kde@fxrh.de>
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * SPDX-License-Identifier: LGPL-2.1-or-later
*/
#pragma once
diff --git a/lib/joinstate.h b/lib/joinstate.h
index 31c2b6a7..1a7b1add 100644
--- a/lib/joinstate.h
+++ b/lib/joinstate.h
@@ -1,19 +1,7 @@
/******************************************************************************
- * Copyright (C) 2015 Felix Rohrbach <kde@fxrh.de>
+ * SPDX-FileCopyrightText: 2015 Felix Rohrbach <kde@fxrh.de>
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * SPDX-License-Identifier: LGPL-2.1-or-later
*/
#pragma once
diff --git a/lib/logging.cpp b/lib/logging.cpp
index c346fbf1..3f757393 100644
--- a/lib/logging.cpp
+++ b/lib/logging.cpp
@@ -1,19 +1,7 @@
/******************************************************************************
- * Copyright (C) 2017 Elvis Angelaccio <elvid.angelaccio@kde.org>
+ * SPDX-FileCopyrightText: 2017 Elvis Angelaccio <elvid.angelaccio@kde.org>
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * SPDX-License-Identifier: LGPL-2.1-or-later
*/
#include "logging.h"
@@ -24,6 +12,7 @@
LOGGING_CATEGORY(MAIN, "quotient.main")
LOGGING_CATEGORY(EVENTS, "quotient.events")
LOGGING_CATEGORY(STATE, "quotient.events.state")
+LOGGING_CATEGORY(MEMBERS, "quotient.events.members")
LOGGING_CATEGORY(MESSAGES, "quotient.events.messages")
LOGGING_CATEGORY(EPHEMERAL, "quotient.events.ephemeral")
LOGGING_CATEGORY(E2EE, "quotient.e2ee")
diff --git a/lib/logging.h b/lib/logging.h
index ce4131bb..21d05d8b 100644
--- a/lib/logging.h
+++ b/lib/logging.h
@@ -1,19 +1,7 @@
/******************************************************************************
- * Copyright (C) 2017 Kitsune Ral <kitsune-ral@users.sf.net>
+ * SPDX-FileCopyrightText: 2017 Kitsune Ral <kitsune-ral@users.sf.net>
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * SPDX-License-Identifier: LGPL-2.1-or-later
*/
#pragma once
@@ -23,6 +11,7 @@
Q_DECLARE_LOGGING_CATEGORY(MAIN)
Q_DECLARE_LOGGING_CATEGORY(STATE)
+Q_DECLARE_LOGGING_CATEGORY(MEMBERS)
Q_DECLARE_LOGGING_CATEGORY(MESSAGES)
Q_DECLARE_LOGGING_CATEGORY(EVENTS)
Q_DECLARE_LOGGING_CATEGORY(EPHEMERAL)
diff --git a/lib/networkaccessmanager.cpp b/lib/networkaccessmanager.cpp
index b9037bcc..43a8287a 100644
--- a/lib/networkaccessmanager.cpp
+++ b/lib/networkaccessmanager.cpp
@@ -1,19 +1,7 @@
/******************************************************************************
- * Copyright (C) 2018 Kitsune Ral <kitsune-ral@users.sf.net>
+ * SPDX-FileCopyrightText: 2018 Kitsune Ral <kitsune-ral@users.sf.net>
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * SPDX-License-Identifier: LGPL-2.1-or-later
*/
#include "networkaccessmanager.h"
@@ -52,9 +40,10 @@ static NetworkAccessManager* createNam()
auto nam = new NetworkAccessManager(QCoreApplication::instance());
#if (QT_VERSION < QT_VERSION_CHECK(5, 15, 0))
// See #109; in newer Qt, bearer management is deprecated altogether
- nam->connect(nam, &QNetworkAccessManager::networkAccessibleChanged, [nam] {
- nam->setNetworkAccessible(QNetworkAccessManager::Accessible);
- });
+ NetworkAccessManager::connect(nam,
+ &QNetworkAccessManager::networkAccessibleChanged, [nam] {
+ nam->setNetworkAccessible(QNetworkAccessManager::Accessible);
+ });
#endif
return nam;
}
diff --git a/lib/networkaccessmanager.h b/lib/networkaccessmanager.h
index a678b80f..6075767a 100644
--- a/lib/networkaccessmanager.h
+++ b/lib/networkaccessmanager.h
@@ -1,19 +1,7 @@
/******************************************************************************
- * Copyright (C) 2018 Kitsune Ral <kitsune-ral@users.sf.net>
+ * SPDX-FileCopyrightText: 2018 Kitsune Ral <kitsune-ral@users.sf.net>
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * SPDX-License-Identifier: LGPL-2.1-or-later
*/
#pragma once
diff --git a/lib/networksettings.cpp b/lib/networksettings.cpp
index 40ecba11..db16034a 100644
--- a/lib/networksettings.cpp
+++ b/lib/networksettings.cpp
@@ -1,19 +1,7 @@
/******************************************************************************
- * Copyright (C) 2017 Kitsune Ral <kitsune-ral@users.sf.net>
+ * SPDX-FileCopyrightText: 2017 Kitsune Ral <kitsune-ral@users.sf.net>
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * SPDX-License-Identifier: LGPL-2.1-or-later
*/
#include "networksettings.h"
diff --git a/lib/networksettings.h b/lib/networksettings.h
index 2399cf5f..31602734 100644
--- a/lib/networksettings.h
+++ b/lib/networksettings.h
@@ -1,19 +1,7 @@
/******************************************************************************
- * Copyright (C) 2017 Kitsune Ral <kitsune-ral@users.sf.net>
+ * SPDX-FileCopyrightText: 2017 Kitsune Ral <kitsune-ral@users.sf.net>
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * SPDX-License-Identifier: LGPL-2.1-or-later
*/
#pragma once
diff --git a/lib/qt_connection_util.h b/lib/qt_connection_util.h
index 699735d4..158d7a40 100644
--- a/lib/qt_connection_util.h
+++ b/lib/qt_connection_util.h
@@ -1,19 +1,7 @@
/******************************************************************************
- * Copyright (C) 2019 Kitsune Ral <kitsune-ral@users.sf.net>
+ * SPDX-FileCopyrightText: 2019 Kitsune Ral <kitsune-ral@users.sf.net>
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * SPDX-License-Identifier: LGPL-2.1-or-later
*/
#pragma once
diff --git a/lib/quotient_common.h b/lib/quotient_common.h
index bb05af05..e2384f12 100644
--- a/lib/quotient_common.h
+++ b/lib/quotient_common.h
@@ -1,3 +1,7 @@
+// SPDX-FileCopyrightText: 2019 Kitsune Ral <Kitsune-Ral@users.sf.net>
+//
+// SPDX-License-Identifier: LGPL-2.1-or-later
+
#pragma once
#include <qobjectdefs.h>
diff --git a/lib/room.cpp b/lib/room.cpp
index a309cd24..bc89464d 100644
--- a/lib/room.cpp
+++ b/lib/room.cpp
@@ -1,19 +1,7 @@
/******************************************************************************
- * Copyright (C) 2015 Felix Rohrbach <kde@fxrh.de>
+ * SPDX-FileCopyrightText: 2015 Felix Rohrbach <kde@fxrh.de>
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * SPDX-License-Identifier: LGPL-2.1-or-later
*/
#include "room.h"
@@ -36,6 +24,7 @@
#include "csapi/room_state.h"
#include "csapi/room_upgrades.h"
#include "csapi/rooms.h"
+#include "csapi/read_markers.h"
#include "csapi/tags.h"
#include "events/callanswerevent.h"
@@ -55,7 +44,6 @@
#include "events/roompowerlevelsevent.h"
#include "jobs/downloadfilejob.h"
#include "jobs/mediathumbnailjob.h"
-#include "jobs/postreadmarkersjob.h"
#include "events/roomcanonicalaliasevent.h"
#include <QtCore/QDir>
@@ -192,7 +180,7 @@ public:
// void inviteUser(User* u); // We might get it at some point in time.
void insertMemberIntoMap(User* u);
- void removeMemberFromMap(const QString& username, User* u);
+ void removeMemberFromMap(User* u);
// This updates the room displayname field (which is the way a room
// should be shown in the room list); called whenever the list of
@@ -263,10 +251,11 @@ public:
for (auto&& eptr : events) {
const auto& evt = *eptr;
Q_ASSERT(evt.isStateEvent());
- // Update baseState afterwards to make sure that the old state
- // is valid and usable inside processStateEvent
- changes |= q->processStateEvent(evt);
- baseState[{ evt.matrixType(), evt.stateKey() }] = move(eptr);
+ auto change = q->processStateEvent(evt);
+ if (change != NoChange) {
+ changes |= change;
+ baseState[{ evt.matrixType(), evt.stateKey() }] = move(eptr);
+ }
}
if (events.size() > 9 || et.nsecsElapsed() >= profilerMinNsecs())
qCDebug(PROFILER)
@@ -350,7 +339,7 @@ public:
*/
bool processReplacement(const RoomMessageEvent& newEvent);
- void setTags(TagsMap newTags);
+ void setTags(TagsMap&& newTags);
QJsonObject toJson() const;
@@ -632,8 +621,8 @@ Room::Changes Room::Private::setLastReadEvent(User* u, QString eventId)
emit q->readMarkerForUserMoved(u, eventId, storedId);
if (isLocalUser(u)) {
if (storedId != serverReadMarker)
- connection->callApi<PostReadMarkersJob>(BackgroundRequest, id,
- storedId);
+ connection->callApi<SetReadMarkerJob>(BackgroundRequest, id,
+ storedId);
emit q->readMarkerMoved(eventId, storedId);
return Change::ReadMarkerChange;
}
@@ -857,7 +846,7 @@ const Room::RelatedEvents Room::relatedEvents(const RoomEvent& evt,
void Room::Private::getAllMembers()
{
// If already loaded or already loading, there's nothing to do here.
- if (q->joinedCount() <= membersMap.size() || isJobRunning(allMembersJob))
+ if (q->joinedCount() <= membersMap.size() || isJobPending(allMembersJob))
return;
allMembersJob = connection->callApi<GetMembersByRoomJob>(
@@ -1010,11 +999,11 @@ TagRecord Room::tag(const QString& name) const { return d->tags.value(name); }
std::pair<bool, QString> validatedTag(QString name)
{
- if (name.contains('.'))
+ if (name.isEmpty() || name.indexOf('.', 1) != -1)
return { false, name };
qCWarning(MAIN) << "The tag" << name
- << "doesn't follow the CS API conventions";
+ << "doesn't follow the CS API conventions";
name.prepend("u.");
qCWarning(MAIN) << "Using " << name << "instead";
@@ -1073,20 +1062,20 @@ void Room::setTags(TagsMap newTags, ActionScope applyOn)
if (propagate) {
for (auto* r = this; (r = r->successor(joinStates));)
- r->setTags(newTags, ActionScope::ThisRoomOnly);
+ r->setTags(d->tags, ActionScope::ThisRoomOnly);
}
}
-void Room::Private::setTags(TagsMap newTags)
+void Room::Private::setTags(TagsMap&& newTags)
{
emit q->tagsAboutToChange();
const auto keys = newTags.keys();
for (const auto& k : keys)
- if (const auto& checkRes = validatedTag(k); checkRes.first) {
- if (newTags.contains(checkRes.second))
+ if (const auto& [adjusted, adjustedTag] = validatedTag(k); adjusted) {
+ if (newTags.contains(adjustedTag))
newTags.remove(k);
else
- newTags.insert(checkRes.second, newTags.take(k));
+ newTags.insert(adjustedTag, newTags.take(k));
}
tags = move(newTags);
@@ -1192,8 +1181,8 @@ QString Room::fileNameToDownload(const QString& eventId) const
FileTransferInfo Room::fileTransferInfo(const QString& id) const
{
- auto infoIt = d->fileTransfers.find(id);
- if (infoIt == d->fileTransfers.end())
+ const auto infoIt = d->fileTransfers.constFind(id);
+ if (infoIt == d->fileTransfers.cend())
return {};
// FIXME: Add lib tests to make sure FileTransferInfo::status stays
@@ -1222,8 +1211,8 @@ QUrl Room::fileSource(const QString& id) const
return url;
// No urlToDownload means it's a pending or completed upload.
- auto infoIt = d->fileTransfers.find(id);
- if (infoIt != d->fileTransfers.end())
+ auto infoIt = d->fileTransfers.constFind(id);
+ if (infoIt != d->fileTransfers.cend())
return QUrl::fromLocalFile(infoIt->localFileInfo.absoluteFilePath());
qCWarning(MAIN) << "File source for identifier" << id << "not found";
@@ -1312,7 +1301,6 @@ void Room::handleRoomKeyEvent(const RoomKeyEvent& roomKeyEvent,
Q_UNUSED(roomKeyEvent)
Q_UNUSED(senderKey)
qCWarning(E2EE) << "End-to-end encryption (E2EE) support is turned off.";
- return;
#else // Quotient_E2EE_ENABLED
if (roomKeyEvent.algorithm() != MegolmV1AesSha2AlgoKey) {
qCWarning(E2EE) << "Ignoring unsupported algorithm"
@@ -1354,14 +1342,27 @@ Room::Changes Room::Private::setSummary(RoomSummary&& newSummary)
void Room::Private::insertMemberIntoMap(User* u)
{
- const auto userName = u->name(q);
- // If there is exactly one namesake of the added user, signal member
- // renaming for that other one because the two should be disambiguated now.
+ const auto maybeUserName =
+ getCurrentState<RoomMemberEvent>(u->id())->newDisplayName();
+ if (!maybeUserName)
+ qCWarning(MEMBERS) << "insertMemberIntoMap():" << u->id()
+ << "has no name (even empty)";
+ const auto userName = maybeUserName.value_or(QString());
const auto namesakes = membersMap.values(userName);
+ qCDebug(MEMBERS) << "insertMemberIntoMap(), user" << u->id()
+ << "with name" << userName << '-'
+ << namesakes.size() << "namesake(s) found";
- // Callers should check they are not adding an existing user once more.
+ // Callers should make sure they are not adding an existing user once more
Q_ASSERT(!namesakes.contains(u));
+ if (namesakes.contains(u)) { // Release version whines but continues
+ qCCritical(MEMBERS) << "Trying to add a user" << u->id() << "to room"
+ << q->objectName() << "but that's already in it";
+ return;
+ }
+ // If there is exactly one namesake of the added user, signal member
+ // renaming for that other one because the two should be disambiguated now
if (namesakes.size() == 1)
emit q->memberAboutToRename(namesakes.front(),
namesakes.front()->fullName(q));
@@ -1370,18 +1371,43 @@ void Room::Private::insertMemberIntoMap(User* u)
emit q->memberRenamed(namesakes.front());
}
-void Room::Private::removeMemberFromMap(const QString& username, User* u)
+void Room::Private::removeMemberFromMap(User* u)
{
+ const auto userName =
+ getCurrentState<RoomMemberEvent>(
+ u->id())->newDisplayName().value_or(QString());
+
+ qCDebug(MEMBERS) << "removeMemberFromMap(), username" << userName
+ << "for user" << u->id();
User* namesake = nullptr;
- auto namesakes = membersMap.values(username);
+ auto namesakes = membersMap.values(userName);
+ // If there was one namesake besides the removed user, signal member
+ // renaming for it because it doesn't need to be disambiguated any more.
if (namesakes.size() == 2) {
- namesake = namesakes.front() == u ? namesakes.back() : namesakes.front();
+ namesake =
+ namesakes.front() == u ? namesakes.back() : namesakes.front();
Q_ASSERT_X(namesake != u, __FUNCTION__, "Room members list is broken");
- emit q->memberAboutToRename(namesake, username);
+ emit q->memberAboutToRename(namesake, userName);
+ }
+ if (membersMap.remove(userName, u) == 0) {
+ qCDebug(MEMBERS) << "No entries removed; checking the whole list";
+ // Unless at the stage of initial filling, this no removed entries
+ // is suspicious; double-check that this user is not found in
+ // the whole map, and stop (for debug builds) or shout in the logs
+ // (for release builds) if there's one. That search is O(n), which
+ // may come rather expensive for larger rooms.
+ QElapsedTimer et;
+ auto it = std::find(membersMap.cbegin(), membersMap.cend(), u);
+ if (et.nsecsElapsed() > profilerMinNsecs() / 10)
+ qCDebug(MEMBERS) << "...done in" << et;
+ if (it != membersMap.cend()) {
+ Q_ASSERT_X(false, __FUNCTION__,
+ "Mismatched name in the room members list");
+ qCCritical(MEMBERS) << "Mismatched name in the room members list;"
+ " avoiding the list corruption";
+ membersMap.remove(it.key(), u);
+ }
}
- membersMap.remove(username, u);
- // If there was one namesake besides the removed user, signal member
- // renaming for it because it doesn't need to be disambiguated any more.
if (namesake)
emit q->memberRenamed(namesake);
}
@@ -1423,7 +1449,7 @@ Room::Private::moveEventsToTimeline(RoomEventsRange events,
}
const auto insertedSize = (index - baseIndex) * placement;
Q_ASSERT(insertedSize == int(events.size()));
- return insertedSize;
+ return Timeline::size_type(insertedSize);
}
QString Room::memberName(const QString& mxId) const
@@ -1639,15 +1665,15 @@ QString Room::retryMessage(const QString& txnId)
const auto it = findPendingEvent(txnId);
Q_ASSERT(it != d->unsyncedEvents.end());
qCDebug(EVENTS) << "Retrying transaction" << txnId;
- const auto& transferIt = d->fileTransfers.find(txnId);
- if (transferIt != d->fileTransfers.end()) {
+ const auto& transferIt = d->fileTransfers.constFind(txnId);
+ if (transferIt != d->fileTransfers.cend()) {
Q_ASSERT(transferIt->isUpload);
if (transferIt->status == FileTransferInfo::Completed) {
qCDebug(MESSAGES)
<< "File for transaction" << txnId
<< "has already been uploaded, bypassing re-upload";
} else {
- if (isJobRunning(transferIt->job)) {
+ if (isJobPending(transferIt->job)) {
qCDebug(MESSAGES) << "Abandoning the upload job for transaction"
<< txnId << "and starting again";
transferIt->job->abandon();
@@ -1680,7 +1706,7 @@ void Room::discardMessage(const QString& txnId)
const auto& transferIt = d->fileTransfers.find(txnId);
if (transferIt != d->fileTransfers.end()) {
Q_ASSERT(transferIt->isUpload);
- if (isJobRunning(transferIt->job)) {
+ if (isJobPending(transferIt->job)) {
transferIt->status = FileTransferInfo::Cancelled;
transferIt->job->abandon();
emit fileTransferFailed(txnId, tr("File upload cancelled"));
@@ -1737,7 +1763,8 @@ QString Room::postFile(const QString& plainText, const QUrl& localPath,
// to enable the preview while the event is pending.
uploadFile(txnId, localPath);
// Below, the upload job is used as a context object to clean up connections
- connect(this, &Room::fileTransferCompleted, d->fileTransfers[txnId].job,
+ const auto& transferJob = d->fileTransfers.value(txnId).job;
+ connect(this, &Room::fileTransferCompleted, transferJob,
[this, txnId](const QString& id, const QUrl&, const QUrl& mxcUri) {
if (id == txnId) {
auto it = findPendingEvent(txnId);
@@ -1756,7 +1783,7 @@ QString Room::postFile(const QString& plainText, const QUrl& localPath,
}
}
});
- connect(this, &Room::fileTransferCancelled, d->fileTransfers[txnId].job,
+ connect(this, &Room::fileTransferCancelled, transferJob,
[this, txnId](const QString& id) {
if (id == txnId) {
auto it = findPendingEvent(txnId);
@@ -1885,7 +1912,7 @@ void Room::getPreviousContent(int limit, const QString &filter) { d->getPrevious
void Room::Private::getPreviousContent(int limit, const QString &filter)
{
- if (isJobRunning(eventsHistoryJob))
+ if (isJobPending(eventsHistoryJob))
return;
eventsHistoryJob =
@@ -1938,7 +1965,7 @@ void Room::uploadFile(const QString& id, const QUrl& localFilename,
"localFilename should point at a local file");
auto fileName = localFilename.toLocalFile();
auto job = connection()->uploadFile(fileName, overrideContentType);
- if (isJobRunning(job)) {
+ if (isJobPending(job)) {
d->fileTransfers[id] = { job, fileName, true };
connect(job, &BaseJob::uploadProgress, this,
[this, id](qint64 sent, qint64 total) {
@@ -1958,8 +1985,8 @@ void Room::uploadFile(const QString& id, const QUrl& localFilename,
void Room::downloadFile(const QString& eventId, const QUrl& localFilename)
{
- auto ongoingTransfer = d->fileTransfers.find(eventId);
- if (ongoingTransfer != d->fileTransfers.end()
+ if (auto ongoingTransfer = d->fileTransfers.constFind(eventId);
+ ongoingTransfer != d->fileTransfers.cend()
&& ongoingTransfer->status == FileTransferInfo::Started) {
qCWarning(MAIN) << "Transfer for" << eventId
<< "is ongoing; download won't start";
@@ -1994,7 +2021,7 @@ void Room::downloadFile(const QString& eventId, const QUrl& localFilename)
qDebug(MAIN) << "File path:" << filePath;
}
auto job = connection()->downloadFile(fileUrl, filePath);
- if (isJobRunning(job)) {
+ if (isJobPending(job)) {
// If there was a previous transfer (completed or failed), overwrite it.
d->fileTransfers[eventId] = { job, job->targetFileName() };
connect(job, &BaseJob::downloadProgress, this,
@@ -2016,13 +2043,13 @@ void Room::downloadFile(const QString& eventId, const QUrl& localFilename)
void Room::cancelFileTransfer(const QString& id)
{
- auto it = d->fileTransfers.find(id);
- if (it == d->fileTransfers.end()) {
+ const auto it = d->fileTransfers.constFind(id);
+ if (it == d->fileTransfers.cend()) {
qCWarning(MAIN) << "No information on file transfer" << id << "in room"
<< d->id;
return;
}
- if (isJobRunning(it->job))
+ if (isJobPending(it->job))
it->job->abandon();
d->fileTransfers.remove(id);
emit fileTransferCancelled(id);
@@ -2119,8 +2146,8 @@ bool Room::Private::processRedaction(const RedactionEvent& redaction)
{
// Can't use findInTimeline because it returns a const iterator, and
// we need to change the underlying TimelineItem.
- const auto pIdx = eventsIndex.find(redaction.redactedEvent());
- if (pIdx == eventsIndex.end())
+ const auto pIdx = eventsIndex.constFind(redaction.redactedEvent());
+ if (pIdx == eventsIndex.cend())
return false;
Q_ASSERT(q->isValidIndex(*pIdx));
@@ -2190,8 +2217,8 @@ bool Room::Private::processReplacement(const RoomMessageEvent& newEvent)
{
// Can't use findInTimeline because it returns a const iterator, and
// we need to change the underlying TimelineItem.
- const auto pIdx = eventsIndex.find(newEvent.replacedEvent());
- if (pIdx == eventsIndex.end())
+ const auto pIdx = eventsIndex.constFind(newEvent.replacedEvent());
+ if (pIdx == eventsIndex.cend())
return false;
Q_ASSERT(q->isValidIndex(*pIdx));
@@ -2434,57 +2461,95 @@ void Room::Private::addHistoricalMessageEvents(RoomEvents&& events)
Room::Changes Room::processStateEvent(const RoomEvent& e)
{
if (!e.isStateEvent())
- return Change::NoChange;
+ return NoChange;
- // Find a value (create empty if necessary) and get a reference to it
- // getCurrentState<> is not used here because it (creates and) returns
+ // Find a value (create an empty one if necessary) and get a reference
+ // to it. Can't use getCurrentState<>() because it (creates and) returns
// a stub if a value is not found, and what's needed here is a "real" event
// or nullptr.
- const auto*& curStateEvent =
- d->currentState[{ e.matrixType(), e.stateKey() }];
+ auto& curStateEvent = d->currentState[{ e.matrixType(), e.stateKey() }];
// Prepare for the state change
- visit(e, [this, oldRme = static_cast<const RoomMemberEvent*>(curStateEvent)](
- const RoomMemberEvent& rme) {
- auto* u = user(rme.userId());
- if (!u) { // ???
- qCCritical(MAIN)
- << "Could not get a user object for" << rme.userId();
- return;
- }
- const auto prevMembership = oldRme ? oldRme->membership()
- : MembershipType::Leave;
- switch (prevMembership) {
- case MembershipType::Invite:
- if (rme.membership() != prevMembership) {
- d->usersInvited.removeOne(u);
- Q_ASSERT(!d->usersInvited.contains(u));
+ // clang-format off
+ const bool proceed = visit(e
+ , [this, curStateEvent](const RoomMemberEvent& rme) {
+ // clang-format on
+ auto* oldRme = static_cast<const RoomMemberEvent*>(curStateEvent);
+ auto* u = user(rme.userId());
+ if (!u) { // Some terribly malformed user id?
+ qCCritical(MAIN) << "Could not get a user object for"
+ << rme.userId();
+ return false; // Stay low and hope for the best...
}
- break;
- case MembershipType::Join:
- switch (rme.membership()) {
- case MembershipType::Join: // rename/avatar change or no-op
- if (rme.newDisplayName()) {
- emit memberAboutToRename(u, *rme.newDisplayName());
- d->removeMemberFromMap(u->name(this), u);
+ const auto prevMembership = oldRme ? oldRme->membership()
+ : MembershipType::Leave;
+ switch (prevMembership) {
+ case MembershipType::Invite:
+ if (rme.membership() != prevMembership) {
+ d->usersInvited.removeOne(u);
+ Q_ASSERT(!d->usersInvited.contains(u));
}
break;
- case MembershipType::Invite:
- qCWarning(MAIN) << "Membership change from Join to Invite:"
- << rme;
- [[fallthrough]];
- default: // whatever the new membership, it's no more Join
- d->removeMemberFromMap(u->name(this), u);
- emit userRemoved(u);
+ case MembershipType::Join:
+ if (rme.membership() == MembershipType::Join) {
+ // rename/avatar change or no-op
+ if (rme.newDisplayName()) {
+ emit memberAboutToRename(u, *rme.newDisplayName());
+ d->removeMemberFromMap(u);
+ }
+ if (!rme.newDisplayName() && !rme.newAvatarUrl()) {
+ qCWarning(MEMBERS)
+ << "No-op membership event for" << rme.userId()
+ << "- retaining the state";
+ qCWarning(MEMBERS) << "The event dump:" << rme;
+ return false;
+ }
+ } else {
+ if (rme.membership() == MembershipType::Invite)
+ qCWarning(MAIN)
+ << "Membership change from Join to Invite:" << rme;
+ // whatever the new membership, it's no more Join
+ d->removeMemberFromMap(u);
+ emit userRemoved(u);
+ }
+ break;
+ case MembershipType::Ban:
+ case MembershipType::Knock:
+ case MembershipType::Leave:
+ if (rme.membership() == MembershipType::Invite
+ || rme.membership() == MembershipType::Join) {
+ d->membersLeft.removeOne(u);
+ Q_ASSERT(!d->membersLeft.contains(u));
+ }
+ break;
+ case MembershipType::Undefined:
+ ; // A warning will be dropped in the post-processing block below
}
- break;
- default:
- if (rme.membership() == MembershipType::Invite
- || rme.membership() == MembershipType::Join) {
- d->membersLeft.removeOne(u);
- Q_ASSERT(!d->membersLeft.contains(u));
+ return true;
+ // clang-format off
+ }
+ , [this, curStateEvent]( const EncryptionEvent& ee) {
+ // clang-format on
+ auto* oldEncEvt =
+ static_cast<const EncryptionEvent*>(curStateEvent);
+ if (ee.algorithm().isEmpty()) {
+ qWarning(STATE)
+ << "The encryption event for room" << objectName()
+ << "doesn't have 'algorithm' specified - ignoring";
+ return false;
}
+ if (oldEncEvt
+ && oldEncEvt->encryption() != EncryptionEventContent::Undefined) {
+ qCWarning(STATE) << "The room is already encrypted but a new"
+ " room encryption event arrived - ignoring";
+ return false;
+ }
+ return true;
+ // clang-format off
}
- });
+ , true); // By default, go forward with the state change
+ // clang-format on
+ if (!proceed)
+ return NoChange;
// Change the state
const auto* const oldStateEvent =
@@ -2492,47 +2557,35 @@ Room::Changes Room::processStateEvent(const RoomEvent& e)
Q_ASSERT(!oldStateEvent
|| (oldStateEvent->matrixType() == e.matrixType()
&& oldStateEvent->stateKey() == e.stateKey()));
- if (!is<RoomMemberEvent>(e)) // Room member events are too numerous
+ if (is<RoomMemberEvent>(e))
+ qCDebug(MEMBERS) << "Updated room member state:" << e;
+ else
qCDebug(STATE) << "Updated room state:" << e;
// Update internal structures as per the change and work out the return value
// clang-format off
- return visit(e
+ const auto result = visit(e
, [] (const RoomNameEvent&) {
return NameChange;
}
- , [] (const RoomAliasesEvent&) {
- return NoChange; // This event has been removed by MSC2432
- }
, [this, oldStateEvent] (const RoomCanonicalAliasEvent& cae) {
// clang-format on
setObjectName(cae.alias().isEmpty() ? d->id : cae.alias());
- QString previousCanonicalAlias =
- oldStateEvent
- ? static_cast<const RoomCanonicalAliasEvent*>(oldStateEvent)
- ->alias()
- : QString();
-
- auto previousAltAliases =
- oldStateEvent
- ? static_cast<const RoomCanonicalAliasEvent*>(oldStateEvent)
- ->altAliases()
- : QStringList();
-
- if (!previousCanonicalAlias.isEmpty()) {
- previousAltAliases.push_back(previousCanonicalAlias);
+ const auto* oldCae =
+ static_cast<const RoomCanonicalAliasEvent*>(oldStateEvent);
+ QStringList previousAltAliases {};
+ if (oldCae) {
+ previousAltAliases = oldCae->altAliases();
+ if (!oldCae->alias().isEmpty())
+ previousAltAliases.push_back(oldCae->alias());
}
- const auto previousAliases = std::move(previousAltAliases);
-
auto newAliases = cae.altAliases();
-
- if (!cae.alias().isEmpty()) {
+ if (!cae.alias().isEmpty())
newAliases.push_front(cae.alias());
- }
- connection()->updateRoomAliases(id(), previousAliases, newAliases);
+ connection()->updateRoomAliases(id(), previousAltAliases, newAliases);
return AliasesChange;
// clang-format off
}
@@ -2572,33 +2625,23 @@ Room::Changes Room::processStateEvent(const RoomEvent& e)
if (u == localUser() && evt.isDirect())
connection()->addToDirectChats(this, user(evt.senderId()));
break;
- default:
+ case MembershipType::Knock:
+ case MembershipType::Ban:
+ case MembershipType::Leave:
if (!d->membersLeft.contains(u))
d->membersLeft.append(u);
+ break;
+ case MembershipType::Undefined:
+ qCWarning(MEMBERS) << "Ignored undefined membership type";
}
return MembersChange;
// clang-format off
}
- , [this, oldEncEvt = static_cast<const EncryptionEvent*>(oldStateEvent)](
- const EncryptionEvent& ee) {
- // clang-format on
- if (ee.algorithm().isEmpty()) {
- qWarning(STATE)
- << "The encryption event for room" << objectName()
- << "doesn't have 'algorithm' specified - ignoring";
- return NoChange;
- }
- if (oldEncEvt
- && oldEncEvt->encryption() != EncryptionEventContent::Undefined) {
- qCWarning(STATE) << "The room is already encrypted but a new"
- " room encryption event arrived - ignoring";
- return NoChange;
- }
+ , [this] (const EncryptionEvent&) {
// As encryption can only be switched on once, emit the signal here
// instead of aggregating and emitting in updateData()
emit encryption();
return OtherChange;
- // clang-format off
}
, [this] (const RoomTombstoneEvent& evt) {
const auto successorId = evt.successorRoomId();
@@ -2615,9 +2658,12 @@ Room::Changes Room::processStateEvent(const RoomEvent& e)
});
return OtherChange;
+ // clang-format off
}
- );
+ , OtherChange);
// clang-format on
+ Q_ASSERT(result != NoChange);
+ return result;
}
Room::Changes Room::processEphemeralEvent(EventPtr&& event)
@@ -2779,7 +2825,7 @@ QString Room::Private::calculateDisplayname() const
const bool localUserIsIn = joinState == JoinState::Join;
const bool emptyRoom =
membersMap.isEmpty()
- || (membersMap.size() == 1 && isLocalUser(*membersMap.begin()));
+ || (membersMap.size() == 1 && isLocalUser(*membersMap.cbegin()));
const bool nonEmptySummary = summary.heroes && !summary.heroes->empty();
auto shortlist = nonEmptySummary ? buildShortlist(*summary.heroes)
: !emptyRoom ? buildShortlist(membersMap)
diff --git a/lib/room.h b/lib/room.h
index f4d7eb70..c9205e9c 100644
--- a/lib/room.h
+++ b/lib/room.h
@@ -1,19 +1,7 @@
/******************************************************************************
- * Copyright (C) 2015 Felix Rohrbach <kde@fxrh.de>
+ * SPDX-FileCopyrightText: 2015 Felix Rohrbach <kde@fxrh.de>
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * SPDX-License-Identifier: LGPL-2.1-or-later
*/
#pragma once
@@ -547,7 +535,7 @@ public:
return setState(EvT(std::forward<ArgTs>(args)...));
}
-public slots:
+public Q_SLOTS:
/** Check whether the room should be upgraded */
void checkVersion();
@@ -611,7 +599,7 @@ public slots:
void answerCall(const QString& callId, const QString& sdp);
void hangupCall(const QString& callId);
-signals:
+Q_SIGNALS:
/// Initial set of state events has been loaded
/**
* The initial set is what comes from the initial sync for the room.
diff --git a/lib/settings.h b/lib/settings.h
index c45764a6..badabec2 100644
--- a/lib/settings.h
+++ b/lib/settings.h
@@ -1,19 +1,7 @@
/******************************************************************************
- * Copyright (C) 2016 Kitsune Ral <kitsune-ral@users.sf.net>
+ * SPDX-FileCopyrightText: 2016 Kitsune Ral <kitsune-ral@users.sf.net>
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * SPDX-License-Identifier: LGPL-2.1-or-later
*/
#pragma once
diff --git a/lib/syncdata.cpp b/lib/syncdata.cpp
index e6472e18..f67ab6c7 100644
--- a/lib/syncdata.cpp
+++ b/lib/syncdata.cpp
@@ -1,19 +1,7 @@
/******************************************************************************
- * Copyright (C) 2018 Kitsune Ral <kitsune-ral@users.sf.net>
+ * SPDX-FileCopyrightText: 2018 Kitsune Ral <kitsune-ral@users.sf.net>
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * SPDX-License-Identifier: LGPL-2.1-or-later
*/
#include "syncdata.h"
diff --git a/lib/syncdata.h b/lib/syncdata.h
index 67d04557..d9868e46 100644
--- a/lib/syncdata.h
+++ b/lib/syncdata.h
@@ -1,19 +1,7 @@
/******************************************************************************
- * Copyright (C) 2018 Kitsune Ral <kitsune-ral@users.sf.net>
+ * SPDX-FileCopyrightText: 2018 Kitsune Ral <kitsune-ral@users.sf.net>
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * SPDX-License-Identifier: LGPL-2.1-or-later
*/
#pragma once
diff --git a/lib/uri.cpp b/lib/uri.cpp
index 8370d83a..e0912eb6 100644
--- a/lib/uri.cpp
+++ b/lib/uri.cpp
@@ -30,7 +30,9 @@ Uri::Uri(QByteArray primaryId, QByteArray secondaryId, QString query)
for (const auto& p: replacePairs)
if (primaryId[0] == p.sigil) {
primaryType_ = Type(p.sigil);
- pathToBe = p.uriString + primaryId.mid(1);
+ auto safePrimaryId = primaryId.mid(1);
+ safePrimaryId.replace('/', "%2F");
+ pathToBe = p.uriString + safePrimaryId;
break;
}
if (!secondaryId.isEmpty()) {
@@ -38,11 +40,40 @@ Uri::Uri(QByteArray primaryId, QByteArray secondaryId, QString query)
primaryType_ = Invalid;
return;
}
- pathToBe += "/event/" + secondaryId.mid(1);
+ auto safeSecondaryId = secondaryId.mid(1);
+ safeSecondaryId.replace('/', "%2F");
+ pathToBe += "/event/" + safeSecondaryId;
}
- setPath(pathToBe);
+ setPath(pathToBe, QUrl::TolerantMode);
}
- setQuery(std::move(query));
+ if (!query.isEmpty())
+ setQuery(query);
+}
+
+static inline auto encodedPath(const QUrl& url)
+{
+ return url.path(QUrl::EncodeDelimiters | QUrl::EncodeUnicode);
+}
+
+static QString pathSegment(const QUrl& url, int which)
+{
+ return QUrl::fromPercentEncoding(
+ encodedPath(url).section('/', which, which).toUtf8());
+}
+
+static auto decodeFragmentPart(const QStringRef& part)
+{
+ return QUrl::fromPercentEncoding(part.toLatin1()).toUtf8();
+}
+
+static auto matrixToUrlRegexInit()
+{
+ // See https://matrix.org/docs/spec/appendices#matrix-to-navigation
+ const QRegularExpression MatrixToUrlRE {
+ "^/(?<main>[^:]+:[^/?]+)(/(?<sec>(\\$|%24)[^?]+))?(\\?(?<query>.+))?$"
+ };
+ Q_ASSERT(MatrixToUrlRE.isValid());
+ return MatrixToUrlRE;
}
Uri::Uri(QUrl url) : QUrl(std::move(url))
@@ -51,14 +82,13 @@ Uri::Uri(QUrl url) : QUrl(std::move(url))
if (isEmpty())
return; // primaryType_ == Empty
- if (!QUrl::isValid()) { // MatrixUri::isValid() checks primaryType_
- primaryType_ = Invalid;
+ primaryType_ = Invalid;
+ if (!QUrl::isValid()) // MatrixUri::isValid() checks primaryType_
return;
- }
if (scheme() == "matrix") {
// Check sanity as per https://github.com/matrix-org/matrix-doc/pull/2312
- const auto& urlPath = path();
+ const auto& urlPath = encodedPath(*this);
const auto& splitPath = urlPath.splitRef('/');
switch (splitPath.size()) {
case 2:
@@ -83,17 +113,15 @@ Uri::Uri(QUrl url) : QUrl(std::move(url))
primaryType_ = NonMatrix; // Default, unless overridden by the code below
if (scheme() == "https" && authority() == "matrix.to") {
- // See https://matrix.org/docs/spec/appendices#matrix-to-navigation
- static const QRegularExpression MatrixToUrlRE {
- R"(^/(?<main>[^/?]+)(/(?<sec>[^?]+))?(\?(?<query>.+))?$)"
- };
+ static const auto MatrixToUrlRE = matrixToUrlRegexInit();
// matrix.to accepts both literal sigils (as well as & and ? used in
// its "query" substitute) and their %-encoded forms;
// so force QUrl to decode everything.
- auto f = fragment(QUrl::FullyDecoded);
+ auto f = fragment(QUrl::EncodeUnicode);
if (auto&& m = MatrixToUrlRE.match(f); m.hasMatch())
- *this = Uri { m.captured("main").toUtf8(),
- m.captured("sec").toUtf8(), m.captured("query") };
+ *this = Uri { decodeFragmentPart(m.capturedRef("main")),
+ decodeFragmentPart(m.capturedRef("sec")),
+ decodeFragmentPart(m.capturedRef("query")) };
}
}
@@ -119,7 +147,7 @@ Uri::Type Uri::type() const { return primaryType_; }
Uri::SecondaryType Uri::secondaryType() const
{
- return path().section('/', 2, 2) == "event" ? EventId : NoSecondaryId;
+ return pathSegment(*this, 2) == "event" ? EventId : NoSecondaryId;
}
QUrl Uri::toUrl(UriForm form) const
@@ -128,7 +156,7 @@ QUrl Uri::toUrl(UriForm form) const
return {};
if (form == CanonicalUri || type() == NonMatrix)
- return *this;
+ return *this; // NOLINT(cppcoreguidelines-slicing): It's intentional
QUrl url;
url.setScheme("https");
@@ -148,13 +176,13 @@ QString Uri::primaryId() const
if (primaryType_ == Empty || primaryType_ == Invalid)
return {};
- const auto& idStem = path().section('/', 1, 1);
+ const auto& idStem = pathSegment(*this, 1);
return idStem.isEmpty() ? idStem : primaryType_ + idStem;
}
QString Uri::secondaryId() const
{
- const auto& idStem = path().section('/', 3);
+ const auto& idStem = pathSegment(*this, 3);
return idStem.isEmpty() ? idStem : secondaryType() + idStem;
}
diff --git a/lib/uriresolver.cpp b/lib/uriresolver.cpp
index ec30512c..27360bcc 100644
--- a/lib/uriresolver.cpp
+++ b/lib/uriresolver.cpp
@@ -75,6 +75,8 @@ private:
std::tuple<FnTs...> fns_;
};
+template <typename... FnTs>
+StaticUriDispatcher(FnTs&&... fns) -> StaticUriDispatcher<FnTs...>;
UriResolveResult Quotient::visitResource(
Connection* account, const Uri& uri,
diff --git a/lib/uriresolver.h b/lib/uriresolver.h
index 9b2ced9d..428ce04c 100644
--- a/lib/uriresolver.h
+++ b/lib/uriresolver.h
@@ -141,7 +141,7 @@ public:
return UriResolverBase::visitResource(account, uri);
}
-signals:
+Q_SIGNALS:
/// An action on a user has been requested
void userAction(Quotient::User* user, QString action);
diff --git a/lib/user.cpp b/lib/user.cpp
index 45a9c121..9c2b76b5 100644
--- a/lib/user.cpp
+++ b/lib/user.cpp
@@ -1,19 +1,7 @@
/******************************************************************************
- * Copyright (C) 2015 Felix Rohrbach <kde@fxrh.de>
+ * SPDX-FileCopyrightText: 2015 Felix Rohrbach <kde@fxrh.de>
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * SPDX-License-Identifier: LGPL-2.1-or-later
*/
#include "user.h"
@@ -78,7 +66,7 @@ QString User::id() const { return d->id; }
bool User::isGuest() const
{
Q_ASSERT(!d->id.isEmpty() && d->id.startsWith('@'));
- auto it = std::find_if_not(d->id.begin() + 1, d->id.end(),
+ auto it = std::find_if_not(d->id.cbegin() + 1, d->id.cend(),
[](QChar c) { return c.isDigit(); });
Q_ASSERT(it != d->id.end());
return *it == ':';
@@ -138,7 +126,7 @@ inline bool User::doSetAvatar(SourceT&& source)
connect(j, &BaseJob::success, this,
[this, newUrl = QUrl(contentUri)] {
if (newUrl == d->defaultAvatar.url()) {
- d->defaultAvatar.updateUrl(move(newUrl));
+ d->defaultAvatar.updateUrl(newUrl);
emit defaultAvatarChanged();
} else
qCWarning(MAIN) << "User" << id()
diff --git a/lib/user.h b/lib/user.h
index a3b22480..d5c892ed 100644
--- a/lib/user.h
+++ b/lib/user.h
@@ -1,19 +1,7 @@
/******************************************************************************
- * Copyright (C) 2015 Felix Rohrbach <kde@fxrh.de>
+ * SPDX-FileCopyrightText: 2015 Felix Rohrbach <kde@fxrh.de>
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * SPDX-License-Identifier: LGPL-2.1-or-later
*/
#pragma once
@@ -122,7 +110,7 @@ public:
QString avatarMediaId(const Room* room = nullptr) const;
QUrl avatarUrl(const Room* room = nullptr) const;
-public slots:
+public Q_SLOTS:
/// Set a new name in the global user profile
void rename(const QString& newName);
/// Set a new name for the user in one room
@@ -143,7 +131,7 @@ public slots:
/// Check whether the user is in ignore list
bool isIgnored() const;
-signals:
+Q_SIGNALS:
void defaultNameChanged();
void defaultAvatarChanged();
diff --git a/lib/util.cpp b/lib/util.cpp
index 0c1c54ff..14492ba6 100644
--- a/lib/util.cpp
+++ b/lib/util.cpp
@@ -1,19 +1,7 @@
/******************************************************************************
- * Copyright (C) 2018 Kitsune Ral <kitsune-ral@users.sf.net>
+ * SPDX-FileCopyrightText: 2018 Kitsune Ral <kitsune-ral@users.sf.net>
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * SPDX-License-Identifier: LGPL-2.1-or-later
*/
#include "util.h"
@@ -161,9 +149,6 @@ static_assert(std::is_same<fn_arg_t<Fo1>, int>(),
"Test fn_arg_t defaulting to first argument");
template <typename T>
-static QString ft(T&&)
-{
- return {};
-}
+static QString ft(T&&);
static_assert(std::is_same<fn_arg_t<decltype(ft<QString>)>, QString&&>(),
"Test function templates");
diff --git a/lib/util.h b/lib/util.h
index 8c92df74..7547a75a 100644
--- a/lib/util.h
+++ b/lib/util.h
@@ -1,19 +1,7 @@
/******************************************************************************
- * Copyright (C) 2016 Kitsune Ral <kitsune-ral@users.sf.net>
+ * SPDX-FileCopyrightText: 2016 Kitsune Ral <kitsune-ral@users.sf.net>
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * SPDX-License-Identifier: LGPL-2.1-or-later
*/
#pragma once
@@ -148,7 +136,7 @@ public:
namespace _impl {
template <typename AlwaysVoid, typename>
- struct fn_traits;
+ struct fn_traits {};
}
/// Determine traits of an arbitrary function/lambda/functor