diff options
Diffstat (limited to 'lib/events')
35 files changed, 1094 insertions, 1088 deletions
diff --git a/lib/events/accountdataevents.h b/lib/events/accountdataevents.h index a99d85ac..0cf2dc60 100644 --- a/lib/events/accountdataevents.h +++ b/lib/events/accountdataevents.h @@ -15,38 +15,37 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #pragma once +#include "converters.h" #include "event.h" #include "eventcontent.h" -#include "converters.h" -namespace QMatrixClient -{ +namespace QMatrixClient { constexpr const char* FavouriteTag = "m.favourite"; constexpr const char* LowPriorityTag = "m.lowpriority"; - struct TagRecord - { + struct TagRecord { using order_type = Omittable<float>; order_type order; - TagRecord (order_type order = none) : order(order) { } + TagRecord(order_type order = none) : order(order) {} bool operator<(const TagRecord& other) const { - // Per The Spec, rooms with no order should be after those with order - return !order.omitted() && - (other.order.omitted() || order.value() < other.order.value()); + // Per The Spec, rooms with no order should be after those with + // order + return !order.omitted() + && (other.order.omitted() + || order.value() < other.order.value()); } }; - template <> struct JsonObjectConverter<TagRecord> - { + template <> struct JsonObjectConverter<TagRecord> { static void fillFrom(const QJsonObject& jo, TagRecord& rec) { // Parse a float both from JSON double and JSON string because @@ -54,8 +53,7 @@ namespace QMatrixClient const auto orderJv = jo.value("order"_ls); if (orderJv.isDouble()) rec.order = fromJson<float>(orderJv); - if (orderJv.isString()) - { + if (orderJv.isString()) { bool ok; rec.order = orderJv.toString().toFloat(&ok); if (!ok) @@ -70,30 +68,31 @@ namespace QMatrixClient using TagsMap = QHash<QString, TagRecord>; -#define DEFINE_SIMPLE_EVENT(_Name, _TypeId, _ContentType, _ContentKey) \ - class _Name : public Event \ - { \ - public: \ - using content_type = _ContentType; \ - DEFINE_EVENT_TYPEID(_TypeId, _Name) \ - explicit _Name(QJsonObject obj) \ - : Event(typeId(), std::move(obj)) \ - { } \ - explicit _Name(_ContentType content) \ - : Event(typeId(), matrixTypeId(), \ - QJsonObject { { QStringLiteral(#_ContentKey), \ - toJson(std::move(content)) } }) \ - { } \ - auto _ContentKey() const \ - { return fromJson<content_type>(contentJson()[#_ContentKey##_ls]); } \ - }; \ - REGISTER_EVENT_TYPE(_Name) \ +#define DEFINE_SIMPLE_EVENT(_Name, _TypeId, _ContentType, _ContentKey) \ + class _Name : public Event \ + { \ + public: \ + using content_type = _ContentType; \ + DEFINE_EVENT_TYPEID(_TypeId, _Name) \ + explicit _Name(QJsonObject obj) : Event(typeId(), std::move(obj)) {} \ + explicit _Name(_ContentType content) \ + : Event(typeId(), matrixTypeId(), \ + QJsonObject { { QStringLiteral(#_ContentKey), \ + toJson(std::move(content)) } }) \ + { \ + } \ + auto _ContentKey() const \ + { \ + return fromJson<content_type>(contentJson()[#_ContentKey##_ls]); \ + } \ + }; \ + REGISTER_EVENT_TYPE(_Name) \ // End of macro DEFINE_SIMPLE_EVENT(TagEvent, "m.tag", TagsMap, tags) DEFINE_SIMPLE_EVENT(ReadMarkerEvent, "m.fully_read", QString, event_id) - DEFINE_SIMPLE_EVENT(IgnoredUsersEvent, "m.ignored_user_list", - QSet<QString>, ignored_users) + DEFINE_SIMPLE_EVENT(IgnoredUsersEvent, "m.ignored_user_list", QSet<QString>, + ignored_users) DEFINE_EVENTTYPE_ALIAS(Tag, TagEvent) DEFINE_EVENTTYPE_ALIAS(ReadMarker, ReadMarkerEvent) diff --git a/lib/events/callanswerevent.cpp b/lib/events/callanswerevent.cpp index d2862241..91e164ad 100644 --- a/lib/events/callanswerevent.cpp +++ b/lib/events/callanswerevent.cpp @@ -13,7 +13,7 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "callanswerevent.h" @@ -56,17 +56,19 @@ CallAnswerEvent::CallAnswerEvent(const QJsonObject& obj) CallAnswerEvent::CallAnswerEvent(const QString& callId, const int lifetime, const QString& sdp) : CallEventBase(typeId(), matrixTypeId(), callId, 0, - { { QStringLiteral("lifetime"), lifetime } - , { QStringLiteral("answer"), QJsonObject { - { QStringLiteral("type"), QStringLiteral("answer") }, - { QStringLiteral("sdp"), sdp } } } - }) -{ } + { { QStringLiteral("lifetime"), lifetime }, + { QStringLiteral("answer"), + QJsonObject { { QStringLiteral("type"), + QStringLiteral("answer") }, + { QStringLiteral("sdp"), sdp } } } }) +{ +} CallAnswerEvent::CallAnswerEvent(const QString& callId, const QString& sdp) : CallEventBase(typeId(), matrixTypeId(), callId, 0, - { { QStringLiteral("answer"), QJsonObject { - { QStringLiteral("type"), QStringLiteral("answer") }, - { QStringLiteral("sdp"), sdp } } } - }) -{ } + { { QStringLiteral("answer"), + QJsonObject { { QStringLiteral("type"), + QStringLiteral("answer") }, + { QStringLiteral("sdp"), sdp } } } }) +{ +} diff --git a/lib/events/callanswerevent.h b/lib/events/callanswerevent.h index 2d9e5bb0..f222803b 100644 --- a/lib/events/callanswerevent.h +++ b/lib/events/callanswerevent.h @@ -13,18 +13,17 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #pragma once #include "roomevent.h" -namespace QMatrixClient -{ - class CallAnswerEvent: public CallEventBase +namespace QMatrixClient { + class CallAnswerEvent : public CallEventBase { - public: + public: DEFINE_EVENT_TYPEID("m.call.answer", CallAnswerEvent) explicit CallAnswerEvent(const QJsonObject& obj); @@ -33,10 +32,16 @@ namespace QMatrixClient const QString& sdp); explicit CallAnswerEvent(const QString& callId, const QString& sdp); - int lifetime() const { return content<int>("lifetime"_ls); } // FIXME: Omittable<>? - QString sdp() const { - return contentJson()["answer"_ls].toObject() - .value("sdp"_ls).toString(); + int lifetime() const + { + return content<int>("lifetime"_ls); + } // FIXME: Omittable<>? + QString sdp() const + { + return contentJson()["answer"_ls] + .toObject() + .value("sdp"_ls) + .toString(); } }; diff --git a/lib/events/callcandidatesevent.cpp b/lib/events/callcandidatesevent.cpp index 52cd1856..24f0dd46 100644 --- a/lib/events/callcandidatesevent.cpp +++ b/lib/events/callcandidatesevent.cpp @@ -13,7 +13,7 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "callcandidatesevent.h" @@ -26,9 +26,8 @@ m.call.candidates "call_id": "12345", "candidates": [ { - "candidate": "candidate:863018703 1 udp 2122260223 10.9.64.156 43670 typ host generation 0", - "sdpMLineIndex": 0, - "sdpMid": "audio" + "candidate": "candidate:863018703 1 udp 2122260223 10.9.64.156 +43670 typ host generation 0", "sdpMLineIndex": 0, "sdpMid": "audio" } ], "version": 0 diff --git a/lib/events/callcandidatesevent.h b/lib/events/callcandidatesevent.h index 4618832c..e66e0c09 100644 --- a/lib/events/callcandidatesevent.h +++ b/lib/events/callcandidatesevent.h @@ -13,34 +13,35 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #pragma once #include "roomevent.h" -namespace QMatrixClient -{ - class CallCandidatesEvent: public CallEventBase +namespace QMatrixClient { + class CallCandidatesEvent : public CallEventBase { public: - DEFINE_EVENT_TYPEID("m.call.candidates", CallCandidatesEvent) + DEFINE_EVENT_TYPEID("m.call.candidates", CallCandidatesEvent) - explicit CallCandidatesEvent(const QJsonObject& obj) - : CallEventBase(typeId(), obj) - { } + explicit CallCandidatesEvent(const QJsonObject& obj) + : CallEventBase(typeId(), obj) + { + } - explicit CallCandidatesEvent(const QString& callId, - const QJsonArray& candidates) - : CallEventBase(typeId(), matrixTypeId(), callId, 0, - {{ QStringLiteral("candidates"), candidates }}) - { } + explicit CallCandidatesEvent(const QString& callId, + const QJsonArray& candidates) + : CallEventBase(typeId(), matrixTypeId(), callId, 0, + { { QStringLiteral("candidates"), candidates } }) + { + } - QJsonArray candidates() const - { - return content<QJsonArray>("candidates"_ls); - } + QJsonArray candidates() const + { + return content<QJsonArray>("candidates"_ls); + } }; REGISTER_EVENT_TYPE(CallCandidatesEvent) diff --git a/lib/events/callhangupevent.cpp b/lib/events/callhangupevent.cpp index b1154806..80844f2d 100644 --- a/lib/events/callhangupevent.cpp +++ b/lib/events/callhangupevent.cpp @@ -13,7 +13,7 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "callhangupevent.h" @@ -42,7 +42,6 @@ m.call.hangup using namespace QMatrixClient; - CallHangupEvent::CallHangupEvent(const QJsonObject& obj) : CallEventBase(typeId(), obj) { @@ -51,4 +50,5 @@ CallHangupEvent::CallHangupEvent(const QJsonObject& obj) CallHangupEvent::CallHangupEvent(const QString& callId) : CallEventBase(typeId(), matrixTypeId(), callId, 0) -{ } +{ +} diff --git a/lib/events/callhangupevent.h b/lib/events/callhangupevent.h index c74e20d5..3c3910be 100644 --- a/lib/events/callhangupevent.h +++ b/lib/events/callhangupevent.h @@ -13,20 +13,19 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #pragma once #include "roomevent.h" -namespace QMatrixClient -{ - class CallHangupEvent: public CallEventBase +namespace QMatrixClient { + class CallHangupEvent : public CallEventBase { - public: + public: DEFINE_EVENT_TYPEID("m.call.hangup", CallHangupEvent) - + explicit CallHangupEvent(const QJsonObject& obj); explicit CallHangupEvent(const QString& callId); }; diff --git a/lib/events/callinviteevent.cpp b/lib/events/callinviteevent.cpp index bca3f296..2459c093 100644 --- a/lib/events/callinviteevent.cpp +++ b/lib/events/callinviteevent.cpp @@ -13,7 +13,7 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "callinviteevent.h" @@ -56,9 +56,10 @@ CallInviteEvent::CallInviteEvent(const QJsonObject& obj) CallInviteEvent::CallInviteEvent(const QString& callId, const int lifetime, const QString& sdp) : CallEventBase(typeId(), matrixTypeId(), callId, lifetime, - { { QStringLiteral("lifetime"), lifetime } - , { QStringLiteral("offer"), QJsonObject { - { QStringLiteral("type"), QStringLiteral("offer") }, - { QStringLiteral("sdp"), sdp } } - }}) -{ } + { { QStringLiteral("lifetime"), lifetime }, + { QStringLiteral("offer"), + QJsonObject { { QStringLiteral("type"), + QStringLiteral("offer") }, + { QStringLiteral("sdp"), sdp } } } }) +{ +} diff --git a/lib/events/callinviteevent.h b/lib/events/callinviteevent.h index d5315309..911ccf96 100644 --- a/lib/events/callinviteevent.h +++ b/lib/events/callinviteevent.h @@ -13,29 +13,34 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #pragma once #include "roomevent.h" -namespace QMatrixClient -{ - class CallInviteEvent: public CallEventBase +namespace QMatrixClient { + class CallInviteEvent : public CallEventBase { - public: + public: DEFINE_EVENT_TYPEID("m.call.invite", CallInviteEvent) - + explicit CallInviteEvent(const QJsonObject& obj); explicit CallInviteEvent(const QString& callId, const int lifetime, const QString& sdp); - int lifetime() const { return content<int>("lifetime"_ls); } // FIXME: Omittable<>? - QString sdp() const { - return contentJson()["offer"_ls].toObject() - .value("sdp"_ls).toString(); + int lifetime() const + { + return content<int>("lifetime"_ls); + } // FIXME: Omittable<>? + QString sdp() const + { + return contentJson()["offer"_ls] + .toObject() + .value("sdp"_ls) + .toString(); } }; diff --git a/lib/events/directchatevent.cpp b/lib/events/directchatevent.cpp index 266d60d8..4ba098c2 100644 --- a/lib/events/directchatevent.cpp +++ b/lib/events/directchatevent.cpp @@ -13,7 +13,7 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "directchatevent.h" @@ -26,13 +26,12 @@ QMultiHash<QString, QString> DirectChatEvent::usersToDirectChats() const { QMultiHash<QString, QString> result; const auto& json = contentJson(); - for (auto it = json.begin(); it != json.end(); ++it) - { + for (auto it = json.begin(); it != json.end(); ++it) { // Beware of range-for's over temporary returned from temporary // (see the bottom of // http://en.cppreference.com/w/cpp/language/range-for#Explanation) const auto roomIds = it.value().toArray(); - for (const auto& roomIdValue: roomIds) + for (const auto& roomIdValue : roomIds) result.insert(it.key(), roomIdValue.toString()); } return result; diff --git a/lib/events/directchatevent.h b/lib/events/directchatevent.h index 7559796b..0d8b8f74 100644 --- a/lib/events/directchatevent.h +++ b/lib/events/directchatevent.h @@ -13,25 +13,24 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #pragma once #include "event.h" -namespace QMatrixClient -{ +namespace QMatrixClient { class DirectChatEvent : public Event { public: - DEFINE_EVENT_TYPEID("m.direct", DirectChatEvent) + DEFINE_EVENT_TYPEID("m.direct", DirectChatEvent) - explicit DirectChatEvent(const QJsonObject& obj) - : Event(typeId(), obj) - { } + explicit DirectChatEvent(const QJsonObject& obj) : Event(typeId(), obj) + { + } - QMultiHash<QString, QString> usersToDirectChats() const; + QMultiHash<QString, QString> usersToDirectChats() const; }; REGISTER_EVENT_TYPE(DirectChatEvent) DEFINE_EVENTTYPE_ALIAS(DirectChat, DirectChatEvent) diff --git a/lib/events/event.cpp b/lib/events/event.cpp index c98dfbb6..f44b1e5d 100644 --- a/lib/events/event.cpp +++ b/lib/events/event.cpp @@ -13,7 +13,7 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "event.h" @@ -31,8 +31,8 @@ event_type_t EventTypeRegistry::initializeTypeId(event_mtype_t matrixTypeId) if (strncmp(matrixTypeId, "", 1) == 0) qDebug(EVENTS) << "Initialized unknown event type with id" << id; else - qDebug(EVENTS) << "Initialized event type" << matrixTypeId - << "with id" << id; + qDebug(EVENTS) << "Initialized event type" << matrixTypeId << "with id" + << id; return id; } @@ -41,32 +41,26 @@ QString EventTypeRegistry::getMatrixType(event_type_t typeId) return typeId < get().eventTypes.size() ? get().eventTypes[typeId] : ""; } -Event::Event(Type type, const QJsonObject& json) - : _type(type), _json(json) +Event::Event(Type type, const QJsonObject& json) : _type(type), _json(json) { - if (!json.contains(ContentKeyL) && - !json.value(UnsignedKeyL).toObject().contains(RedactedCauseKeyL)) - { + if (!json.contains(ContentKeyL) + && !json.value(UnsignedKeyL).toObject().contains(RedactedCauseKeyL)) { qCWarning(EVENTS) << "Event without 'content' node"; qCWarning(EVENTS) << formatJson << json; } } -Event::Event(Type type, event_mtype_t matrixType, const QJsonObject& contentJson) +Event::Event(Type type, event_mtype_t matrixType, + const QJsonObject& contentJson) : Event(type, basicEventJson(matrixType, contentJson)) -{ } +{ +} Event::~Event() = default; -QString Event::matrixType() const -{ - return fullJson()[TypeKeyL].toString(); -} +QString Event::matrixType() const { return fullJson()[TypeKeyL].toString(); } -QByteArray Event::originalJson() const -{ - return QJsonDocument(_json).toJson(); -} +QByteArray Event::originalJson() const { return QJsonDocument(_json).toJson(); } const QJsonObject Event::contentJson() const { diff --git a/lib/events/event.h b/lib/events/event.h index d7ac4292..a0f12b75 100644 --- a/lib/events/event.h +++ b/lib/events/event.h @@ -13,7 +13,7 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #pragma once @@ -25,12 +25,10 @@ #define USE_EVENTTYPE_ALIAS 1 #endif -namespace QMatrixClient -{ +namespace QMatrixClient { // === event_ptr_tt<> and type casting facilities === - template <typename EventT> - using event_ptr_tt = std::unique_ptr<EventT>; + template <typename EventT> using event_ptr_tt = std::unique_ptr<EventT>; template <typename EventT> inline EventT* rawPtr(const event_ptr_tt<EventT>& ptr) // unwrap @@ -80,50 +78,46 @@ namespace QMatrixClient class EventTypeRegistry { public: - ~EventTypeRegistry() = default; + ~EventTypeRegistry() = default; - static event_type_t initializeTypeId(event_mtype_t matrixTypeId); + static event_type_t initializeTypeId(event_mtype_t matrixTypeId); - template <typename EventT> - static inline event_type_t initializeTypeId() - { - return initializeTypeId(EventT::matrixTypeId()); - } + template <typename EventT> static inline event_type_t initializeTypeId() + { + return initializeTypeId(EventT::matrixTypeId()); + } - static QString getMatrixType(event_type_t typeId); + static QString getMatrixType(event_type_t typeId); private: - EventTypeRegistry() = default; - Q_DISABLE_COPY(EventTypeRegistry) - DISABLE_MOVE(EventTypeRegistry) + EventTypeRegistry() = default; + Q_DISABLE_COPY(EventTypeRegistry) + DISABLE_MOVE(EventTypeRegistry) - static EventTypeRegistry& get() - { - static EventTypeRegistry etr; - return etr; - } + static EventTypeRegistry& get() + { + static EventTypeRegistry etr; + return etr; + } - std::vector<event_mtype_t> eventTypes; + std::vector<event_mtype_t> eventTypes; }; - template <> - inline event_type_t EventTypeRegistry::initializeTypeId<void>() + template <> inline event_type_t EventTypeRegistry::initializeTypeId<void>() { return initializeTypeId(""); } - template <typename EventT> - struct EventTypeTraits - { + template <typename EventT> struct EventTypeTraits { static event_type_t id() { - static const auto id = EventTypeRegistry::initializeTypeId<EventT>(); + static const auto id = + EventTypeRegistry::initializeTypeId<EventT>(); return id; } }; - template <typename EventT> - inline event_type_t typeId() + template <typename EventT> inline event_type_t typeId() { return EventTypeTraits<std::decay_t<EventT>>::id(); } @@ -139,49 +133,45 @@ namespace QMatrixClient return std::make_unique<EventT>(std::forward<ArgTs>(args)...); } - template <typename BaseEventT> - class EventFactory + template <typename BaseEventT> class EventFactory { public: - template <typename FnT> - static auto addMethod(FnT&& method) - { - factories().emplace_back(std::forward<FnT>(method)); - return 0; - } - - /** Chain two type factories - * Adds the factory class of EventT2 (EventT2::factory_t) to - * the list in factory class of EventT1 (EventT1::factory_t) so - * that when EventT1::factory_t::make() is invoked, types of - * EventT2 factory are looked through as well. This is used - * to include RoomEvent types into the more general Event factory, - * and state event types into the RoomEvent factory. - */ - template <typename EventT> - static auto chainFactory() - { - return addMethod(&EventT::factory_t::make); - } - - static event_ptr_tt<BaseEventT> make(const QJsonObject& json, - const QString& matrixType) - { - for (const auto& f: factories()) - if (auto e = f(json, matrixType)) - return e; - return nullptr; - } + template <typename FnT> static auto addMethod(FnT&& method) + { + factories().emplace_back(std::forward<FnT>(method)); + return 0; + } + + /** Chain two type factories + * Adds the factory class of EventT2 (EventT2::factory_t) to + * the list in factory class of EventT1 (EventT1::factory_t) so + * that when EventT1::factory_t::make() is invoked, types of + * EventT2 factory are looked through as well. This is used + * to include RoomEvent types into the more general Event factory, + * and state event types into the RoomEvent factory. + */ + template <typename EventT> static auto chainFactory() + { + return addMethod(&EventT::factory_t::make); + } + + static event_ptr_tt<BaseEventT> make(const QJsonObject& json, + const QString& matrixType) + { + for (const auto& f : factories()) + if (auto e = f(json, matrixType)) + return e; + return nullptr; + } private: - static auto& factories() - { - using inner_factory_tt = - std::function<event_ptr_tt<BaseEventT>(const QJsonObject&, - const QString&)>; - static std::vector<inner_factory_tt> _factories {}; - return _factories; - } + static auto& factories() + { + using inner_factory_tt = std::function<event_ptr_tt<BaseEventT>( + const QJsonObject&, const QString&)>; + static std::vector<inner_factory_tt> _factories {}; + return _factories; + } }; /** Add a type to its default factory @@ -193,20 +183,18 @@ namespace QMatrixClient * \return the registered type id * \sa loadEvent, Event::type */ - template <typename EventT> - inline auto setupFactory() + template <typename EventT> inline auto setupFactory() { qDebug(EVENTS) << "Adding factory method for" << EventT::matrixTypeId(); return EventT::factory_t::addMethod( - [] (const QJsonObject& json, const QString& jsonMatrixType) - { - return EventT::matrixTypeId() == jsonMatrixType - ? makeEvent<EventT>(json) : nullptr; - }); + [](const QJsonObject& json, const QString& jsonMatrixType) { + return EventT::matrixTypeId() == jsonMatrixType + ? makeEvent<EventT>(json) + : nullptr; + }); } - template <typename EventT> - inline auto registerEventType() + template <typename EventT> inline auto registerEventType() { // Initialise exactly once, even if this function is called twice for // the same type (for whatever reason - you never know the ways of @@ -219,66 +207,64 @@ namespace QMatrixClient class Event { - Q_GADGET - Q_PROPERTY(Type type READ type CONSTANT) - Q_PROPERTY(QJsonObject contentJson READ contentJson CONSTANT) + Q_GADGET + Q_PROPERTY(Type type READ type CONSTANT) + Q_PROPERTY(QJsonObject contentJson READ contentJson CONSTANT) public: - using Type = event_type_t; - using factory_t = EventFactory<Event>; - - explicit Event(Type type, const QJsonObject& json); - explicit Event(Type type, event_mtype_t matrixType, - const QJsonObject& contentJson = {}); - Q_DISABLE_COPY(Event) - Event(Event&&) = default; - Event& operator=(Event&&) = delete; - virtual ~Event(); - - Type type() const { return _type; } - QString matrixType() const; - QByteArray originalJson() const; - QJsonObject originalJsonObject() const { return fullJson(); } - - const QJsonObject& fullJson() const { return _json; } - - // According to the CS API spec, every event also has - // a "content" object; but since its structure is different for - // different types, we're implementing it per-event type. - - const QJsonObject contentJson() const; - const QJsonObject unsignedJson() const; - - template <typename T> - T content(const QString& key) const - { - return fromJson<T>(contentJson()[key]); - } - - template <typename T> - T content(const QLatin1String& key) const - { - return fromJson<T>(contentJson()[key]); - } - - friend QDebug operator<<(QDebug dbg, const Event& e) - { - QDebugStateSaver _dss { dbg }; - dbg.noquote().nospace() - << e.matrixType() << '(' << e.type() << "): "; - e.dumpTo(dbg); - return dbg; - } - - virtual bool isStateEvent() const { return false; } - virtual bool isCallEvent() const { return false; } - virtual void dumpTo(QDebug dbg) const; + using Type = event_type_t; + using factory_t = EventFactory<Event>; + + explicit Event(Type type, const QJsonObject& json); + explicit Event(Type type, event_mtype_t matrixType, + const QJsonObject& contentJson = {}); + Q_DISABLE_COPY(Event) + Event(Event&&) = default; + Event& operator=(Event&&) = delete; + virtual ~Event(); + + Type type() const { return _type; } + QString matrixType() const; + QByteArray originalJson() const; + QJsonObject originalJsonObject() const { return fullJson(); } + + const QJsonObject& fullJson() const { return _json; } + + // According to the CS API spec, every event also has + // a "content" object; but since its structure is different for + // different types, we're implementing it per-event type. + + const QJsonObject contentJson() const; + const QJsonObject unsignedJson() const; + + template <typename T> T content(const QString& key) const + { + return fromJson<T>(contentJson()[key]); + } + + template <typename T> T content(const QLatin1String& key) const + { + return fromJson<T>(contentJson()[key]); + } + + friend QDebug operator<<(QDebug dbg, const Event& e) + { + QDebugStateSaver _dss { dbg }; + dbg.noquote().nospace() + << e.matrixType() << '(' << e.type() << "): "; + e.dumpTo(dbg); + return dbg; + } + + virtual bool isStateEvent() const { return false; } + virtual bool isCallEvent() const { return false; } + virtual void dumpTo(QDebug dbg) const; protected: - QJsonObject& editJson() { return _json; } + QJsonObject& editJson() { return _json; } private: - Type _type; - QJsonObject _json; + Type _type; + QJsonObject _json; }; using EventPtr = event_ptr_tt<Event>; @@ -290,24 +276,23 @@ namespace QMatrixClient // This macro should be used in a public section of an event class to // provide matrixTypeId() and typeId(). -#define DEFINE_EVENT_TYPEID(_Id, _Type) \ - static constexpr event_mtype_t matrixTypeId() { return _Id; } \ - static auto typeId() { return QMatrixClient::typeId<_Type>(); } \ +#define DEFINE_EVENT_TYPEID(_Id, _Type) \ + static constexpr event_mtype_t matrixTypeId() { return _Id; } \ + static auto typeId() { return QMatrixClient::typeId<_Type>(); } \ // End of macro // This macro should be put after an event class definition (in .h or .cpp) // to enable its deserialisation from a /sync and other // polymorphic event arrays -#define REGISTER_EVENT_TYPE(_Type) \ - namespace { \ - [[gnu::unused]] \ - static const auto _factoryAdded##_Type = registerEventType<_Type>(); \ - } \ +#define REGISTER_EVENT_TYPE(_Type) \ + namespace { \ + [[gnu::unused]] static const auto _factoryAdded##_Type = \ + registerEventType<_Type>(); \ + } \ // End of macro #ifdef USE_EVENTTYPE_ALIAS - namespace EventType - { + namespace EventType { inline event_type_t logEventType(event_type_t id, const char* idName) { qDebug(EVENTS) << "Using id" << id << "for" << idName; @@ -317,12 +302,12 @@ namespace QMatrixClient // This macro provides constants in EventType:: namespace for // back-compatibility with libQMatrixClient 0.3 event type system. -#define DEFINE_EVENTTYPE_ALIAS(_Id, _Type) \ - namespace EventType \ - { \ - [[deprecated("Use is<>(), eventCast<>() or visit<>()")]] \ - static const auto _Id = logEventType(typeId<_Type>(), #_Id); \ - } \ +#define DEFINE_EVENTTYPE_ALIAS(_Id, _Type) \ + namespace EventType { \ + [[deprecated( \ + "Use is<>(), eventCast<>() or visit<>()")]] static const auto \ + _Id = logEventType(typeId<_Type>(), #_Id); \ + } \ // End of macro #else #define DEFINE_EVENTTYPE_ALIAS(_Id, _Type) // Nothing @@ -330,46 +315,48 @@ namespace QMatrixClient // === is<>(), eventCast<>() and visit<>() === - template <typename EventT> - inline bool is(const Event& e) { return e.type() == typeId<EventT>(); } + template <typename EventT> inline bool is(const Event& e) + { + return e.type() == typeId<EventT>(); + } - inline bool isUnknown(const Event& e) { return e.type() == unknownEventTypeId(); } + inline bool isUnknown(const Event& e) + { + return e.type() == unknownEventTypeId(); + } template <typename EventT, typename BasePtrT> inline auto eventCast(const BasePtrT& eptr) - -> decltype(static_cast<EventT*>(&*eptr)) + -> decltype(static_cast<EventT*>(&*eptr)) { Q_ASSERT(eptr); - return is<std::decay_t<EventT>>(*eptr) - ? static_cast<EventT*>(&*eptr) : nullptr; + return is<std::decay_t<EventT>>(*eptr) ? static_cast<EventT*>(&*eptr) + : nullptr; } // A single generic catch-all visitor template <typename BaseEventT, typename FnT> inline auto visit(const BaseEventT& event, FnT&& visitor) - -> decltype(visitor(event)) + -> decltype(visitor(event)) { return visitor(event); } - template <typename T> - constexpr auto is_event() + template <typename T> constexpr auto is_event() { return std::is_base_of<Event, std::decay_t<T>>::value; } - template <typename T, typename FnT> - constexpr auto needs_cast() + template <typename T, typename FnT> constexpr auto needs_cast() { return !std::is_convertible<T, fn_arg_t<FnT>>::value; } // A single type-specific void visitor template <typename BaseEventT, typename FnT> - inline - std::enable_if_t< - is_event<BaseEventT>() && needs_cast<BaseEventT, FnT>() && - std::is_void<fn_return_t<FnT>>::value> + inline std::enable_if_t<is_event<BaseEventT>() + && needs_cast<BaseEventT, FnT>() + && std::is_void<fn_return_t<FnT>>::value> visit(const BaseEventT& event, FnT&& visitor) { using event_type = fn_arg_t<FnT>; @@ -379,10 +366,9 @@ namespace QMatrixClient // A single type-specific non-void visitor with an optional default value template <typename BaseEventT, typename FnT> - inline - std::enable_if_t< - is_event<BaseEventT>() && needs_cast<BaseEventT, FnT>(), - fn_return_t<FnT>> // non-voidness is guarded by defaultValue type + inline std::enable_if_t< + is_event<BaseEventT>() && needs_cast<BaseEventT, FnT>(), + fn_return_t<FnT>> // non-voidness is guarded by defaultValue type visit(const BaseEventT& event, FnT&& visitor, fn_return_t<FnT>&& defaultValue = {}) { @@ -393,9 +379,9 @@ namespace QMatrixClient } // A chain of 2 or more visitors - template <typename BaseEventT, typename FnT1, typename FnT2, typename... FnTs> - inline - std::enable_if_t<is_event<BaseEventT>(), fn_return_t<FnT1>> + template <typename BaseEventT, typename FnT1, typename FnT2, + typename... FnTs> + inline std::enable_if_t<is_event<BaseEventT>(), fn_return_t<FnT1>> visit(const BaseEventT& event, FnT1&& visitor1, FnT2&& visitor2, FnTs&&... visitors) { @@ -405,6 +391,6 @@ namespace QMatrixClient return visit(event, std::forward<FnT2>(visitor2), std::forward<FnTs>(visitors)...); } -} // namespace QMatrixClient +} // namespace QMatrixClient Q_DECLARE_METATYPE(QMatrixClient::Event*) Q_DECLARE_METATYPE(const QMatrixClient::Event*) diff --git a/lib/events/eventcontent.cpp b/lib/events/eventcontent.cpp index 9a5e872c..cc31fea5 100644 --- a/lib/events/eventcontent.cpp +++ b/lib/events/eventcontent.cpp @@ -13,7 +13,7 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "eventcontent.h" @@ -34,17 +34,21 @@ QJsonObject Base::toJson() const FileInfo::FileInfo(const QUrl& u, qint64 payloadSize, const QMimeType& mimeType, const QString& originalFilename) - : mimeType(mimeType), url(u), payloadSize(payloadSize) - , originalName(originalFilename) -{ } + : mimeType(mimeType), + url(u), + payloadSize(payloadSize), + originalName(originalFilename) +{ +} FileInfo::FileInfo(const QUrl& u, const QJsonObject& infoJson, const QString& originalFilename) - : originalInfoJson(infoJson) - , mimeType(QMimeDatabase().mimeTypeForName(infoJson["mimetype"_ls].toString())) - , url(u) - , payloadSize(fromJson<qint64>(infoJson["size"_ls])) - , originalName(originalFilename) + : originalInfoJson(infoJson), + mimeType(QMimeDatabase().mimeTypeForName( + infoJson["mimetype"_ls].toString())), + url(u), + payloadSize(fromJson<qint64>(infoJson["size"_ls])), + originalName(originalFilename) { if (!mimeType.isValid()) mimeType = QMimeDatabase().mimeTypeForData(QByteArray()); @@ -62,13 +66,15 @@ void FileInfo::fillInfoJson(QJsonObject* infoJson) const ImageInfo::ImageInfo(const QUrl& u, qint64 fileSize, QMimeType mimeType, const QSize& imageSize, const QString& originalFilename) : FileInfo(u, fileSize, mimeType, originalFilename), imageSize(imageSize) -{ } +{ +} ImageInfo::ImageInfo(const QUrl& u, const QJsonObject& infoJson, const QString& originalFilename) - : FileInfo(u, infoJson, originalFilename) - , imageSize(infoJson["w"_ls].toInt(), infoJson["h"_ls].toInt()) -{ } + : FileInfo(u, infoJson, originalFilename), + imageSize(infoJson["w"_ls].toInt(), infoJson["h"_ls].toInt()) +{ +} void ImageInfo::fillInfoJson(QJsonObject* infoJson) const { @@ -82,7 +88,8 @@ void ImageInfo::fillInfoJson(QJsonObject* infoJson) const Thumbnail::Thumbnail(const QJsonObject& infoJson) : ImageInfo(infoJson["thumbnail_url"_ls].toString(), infoJson["thumbnail_info"_ls].toObject()) -{ } +{ +} void Thumbnail::fillInfoJson(QJsonObject* infoJson) const { diff --git a/lib/events/eventcontent.h b/lib/events/eventcontent.h index 0588c0e2..857e7369 100644 --- a/lib/events/eventcontent.h +++ b/lib/events/eventcontent.h @@ -13,7 +13,7 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #pragma once @@ -23,13 +23,11 @@ #include <QtCore/QJsonObject> #include <QtCore/QMimeType> -#include <QtCore/QUrl> #include <QtCore/QSize> +#include <QtCore/QUrl> -namespace QMatrixClient -{ - namespace EventContent - { +namespace QMatrixClient { + namespace EventContent { /** * A base class for all content types that can be stored * in a RoomMessageEvent @@ -43,17 +41,17 @@ namespace QMatrixClient class Base { public: - explicit Base (QJsonObject o = {}) : originalJson(std::move(o)) { } - virtual ~Base() = default; + explicit Base(QJsonObject o = {}) : originalJson(std::move(o)) {} + virtual ~Base() = default; - // FIXME: make toJson() from converters.* work on base classes - QJsonObject toJson() const; + // FIXME: make toJson() from converters.* work on base classes + QJsonObject toJson() const; public: - QJsonObject originalJson; + QJsonObject originalJson; protected: - virtual void fillJson(QJsonObject* o) const = 0; + virtual void fillJson(QJsonObject* o) const = 0; }; // The below structures fairly follow CS spec 11.2.1.6. The overall @@ -81,40 +79,40 @@ namespace QMatrixClient * JSON content, as well as contents of "url" (or a similar key) and * optionally "filename" node from the main JSON content. Assuming you * don't do unusual things, you should use \p UrlBasedContent<> instead - * of doing multiple inheritance and overriding Base::fillJson() by hand. + * of doing multiple inheritance and overriding Base::fillJson() by + * hand. * * This class is not polymorphic. */ class FileInfo { public: - explicit FileInfo(const QUrl& u, qint64 payloadSize = -1, - const QMimeType& mimeType = {}, - const QString& originalFilename = {}); - FileInfo(const QUrl& u, const QJsonObject& infoJson, - const QString& originalFilename = {}); + explicit FileInfo(const QUrl& u, qint64 payloadSize = -1, + const QMimeType& mimeType = {}, + const QString& originalFilename = {}); + FileInfo(const QUrl& u, const QJsonObject& infoJson, + const QString& originalFilename = {}); - void fillInfoJson(QJsonObject* infoJson) const; + void fillInfoJson(QJsonObject* infoJson) const; - /** - * \brief Extract media id from the URL - * - * This can be used, e.g., to construct a QML-facing image:// - * URI as follows: - * \code "image://provider/" + info.mediaId() \endcode - */ - QString mediaId() const { return url.authority() + url.path(); } + /** + * \brief Extract media id from the URL + * + * This can be used, e.g., to construct a QML-facing image:// + * URI as follows: + * \code "image://provider/" + info.mediaId() \endcode + */ + QString mediaId() const { return url.authority() + url.path(); } public: - QJsonObject originalInfoJson; - QMimeType mimeType; - QUrl url; - qint64 payloadSize; - QString originalName; + QJsonObject originalInfoJson; + QMimeType mimeType; + QUrl url; + qint64 payloadSize; + QString originalName; }; - template <typename InfoT> - QJsonObject toInfoJson(const InfoT& info) + template <typename InfoT> QJsonObject toInfoJson(const InfoT& info) { QJsonObject infoJson; info.fillInfoJson(&infoJson); @@ -127,17 +125,17 @@ namespace QMatrixClient class ImageInfo : public FileInfo { public: - explicit ImageInfo(const QUrl& u, qint64 fileSize = -1, - QMimeType mimeType = {}, - const QSize& imageSize = {}, - const QString& originalFilename = {}); - ImageInfo(const QUrl& u, const QJsonObject& infoJson, - const QString& originalFilename = {}); + explicit ImageInfo(const QUrl& u, qint64 fileSize = -1, + QMimeType mimeType = {}, + const QSize& imageSize = {}, + const QString& originalFilename = {}); + ImageInfo(const QUrl& u, const QJsonObject& infoJson, + const QString& originalFilename = {}); - void fillInfoJson(QJsonObject* infoJson) const; + void fillInfoJson(QJsonObject* infoJson) const; public: - QSize imageSize; + QSize imageSize; }; /** @@ -150,26 +148,26 @@ namespace QMatrixClient class Thumbnail : public ImageInfo { public: - Thumbnail() : ImageInfo(QUrl()) { } // To allow empty thumbnails - Thumbnail(const QJsonObject& infoJson); - Thumbnail(const ImageInfo& info) : ImageInfo(info) { } - using ImageInfo::ImageInfo; + Thumbnail() : ImageInfo(QUrl()) {} // To allow empty thumbnails + Thumbnail(const QJsonObject& infoJson); + Thumbnail(const ImageInfo& info) : ImageInfo(info) {} + using ImageInfo::ImageInfo; - /** - * Writes thumbnail information to "thumbnail_info" subobject - * and thumbnail URL to "thumbnail_url" node inside "info". - */ - void fillInfoJson(QJsonObject* infoJson) const; + /** + * Writes thumbnail information to "thumbnail_info" subobject + * and thumbnail URL to "thumbnail_url" node inside "info". + */ + void fillInfoJson(QJsonObject* infoJson) const; }; - class TypedBase: public Base + class TypedBase : public Base { public: - explicit TypedBase(const QJsonObject& o = {}) : Base(o) { } - virtual QMimeType type() const = 0; - virtual const FileInfo* fileInfo() const { return nullptr; } - virtual FileInfo* fileInfo() { return nullptr; } - virtual const Thumbnail* thumbnailInfo() const { return nullptr; } + explicit TypedBase(const QJsonObject& o = {}) : Base(o) {} + virtual QMimeType type() const = 0; + virtual const FileInfo* fileInfo() const { return nullptr; } + virtual FileInfo* fileInfo() { return nullptr; } + virtual const Thumbnail* thumbnailInfo() const { return nullptr; } }; /** @@ -186,59 +184,61 @@ namespace QMatrixClient class UrlBasedContent : public TypedBase, public InfoT { public: - using InfoT::InfoT; - explicit UrlBasedContent(const QJsonObject& json) - : TypedBase(json) - , InfoT(json["url"].toString(), json["info"].toObject(), - json["filename"].toString()) - { - // A small hack to facilitate links creation in QML. - originalJson.insert("mediaId", InfoT::mediaId()); - } + using InfoT::InfoT; + explicit UrlBasedContent(const QJsonObject& json) + : TypedBase(json), + InfoT(json["url"].toString(), json["info"].toObject(), + json["filename"].toString()) + { + // A small hack to facilitate links creation in QML. + originalJson.insert("mediaId", InfoT::mediaId()); + } - QMimeType type() const override { return InfoT::mimeType; } - const FileInfo* fileInfo() const override { return this; } - FileInfo* fileInfo() override { return this; } + QMimeType type() const override { return InfoT::mimeType; } + const FileInfo* fileInfo() const override { return this; } + FileInfo* fileInfo() override { return this; } protected: - void fillJson(QJsonObject* json) const override - { - Q_ASSERT(json); - json->insert("url", InfoT::url.toString()); - if (!InfoT::originalName.isEmpty()) - json->insert("filename", InfoT::originalName); - json->insert("info", toInfoJson<InfoT>(*this)); - } + void fillJson(QJsonObject* json) const override + { + Q_ASSERT(json); + json->insert("url", InfoT::url.toString()); + if (!InfoT::originalName.isEmpty()) + json->insert("filename", InfoT::originalName); + json->insert("info", toInfoJson<InfoT>(*this)); + } }; template <typename InfoT> class UrlWithThumbnailContent : public UrlBasedContent<InfoT> { public: - using UrlBasedContent<InfoT>::UrlBasedContent; - explicit UrlWithThumbnailContent(const QJsonObject& json) - : UrlBasedContent<InfoT>(json) - , thumbnail(InfoT::originalInfoJson) - { - // Another small hack, to simplify making a thumbnail link - UrlBasedContent<InfoT>::originalJson.insert( - "thumbnailMediaId", thumbnail.mediaId()); - } + using UrlBasedContent<InfoT>::UrlBasedContent; + explicit UrlWithThumbnailContent(const QJsonObject& json) + : UrlBasedContent<InfoT>(json), + thumbnail(InfoT::originalInfoJson) + { + // Another small hack, to simplify making a thumbnail link + UrlBasedContent<InfoT>::originalJson.insert( + "thumbnailMediaId", thumbnail.mediaId()); + } - const Thumbnail* thumbnailInfo() const override - { return &thumbnail; } + const Thumbnail* thumbnailInfo() const override + { + return &thumbnail; + } public: - Thumbnail thumbnail; + Thumbnail thumbnail; protected: - void fillJson(QJsonObject* json) const override - { - UrlBasedContent<InfoT>::fillJson(json); - auto infoJson = json->take("info").toObject(); - thumbnail.fillInfoJson(&infoJson); - json->insert("info", infoJson); - } + void fillJson(QJsonObject* json) const override + { + UrlBasedContent<InfoT>::fillJson(json); + auto infoJson = json->take("info").toObject(); + thumbnail.fillInfoJson(&infoJson); + json->insert("info", infoJson); + } }; /** @@ -278,5 +278,5 @@ namespace QMatrixClient * - thumbnail.imageSize (QSize for "h" and "w" in JSON) */ using FileContent = UrlWithThumbnailContent<FileInfo>; - } // namespace EventContent -} // namespace QMatrixClient + } // namespace EventContent +} // namespace QMatrixClient diff --git a/lib/events/eventloader.h b/lib/events/eventloader.h index da663392..a19a83b6 100644 --- a/lib/events/eventloader.h +++ b/lib/events/eventloader.h @@ -1,20 +1,20 @@ /****************************************************************************** -* Copyright (C) 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 -*/ + * Copyright (C) 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 + */ #pragma once @@ -57,8 +57,7 @@ namespace QMatrixClient { matrixType); } - template <typename EventT> struct JsonConverter<event_ptr_tt<EventT>> - { + template <typename EventT> struct JsonConverter<event_ptr_tt<EventT>> { static auto load(const QJsonValue& jv) { return loadEvent<EventT>(jv.toObject()); diff --git a/lib/events/receiptevent.cpp b/lib/events/receiptevent.cpp index 47e1398c..76c7b6e4 100644 --- a/lib/events/receiptevent.cpp +++ b/lib/events/receiptevent.cpp @@ -13,7 +13,7 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /* @@ -40,30 +40,27 @@ Example of a Receipt Event: using namespace QMatrixClient; -ReceiptEvent::ReceiptEvent(const QJsonObject& obj) - : Event(typeId(), obj) +ReceiptEvent::ReceiptEvent(const QJsonObject& obj) : Event(typeId(), obj) { const auto& contents = contentJson(); _eventsWithReceipts.reserve(contents.size()); - for( auto eventIt = contents.begin(); eventIt != contents.end(); ++eventIt ) - { - if (eventIt.key().isEmpty()) - { - qCWarning(EPHEMERAL) << "ReceiptEvent has an empty event id, skipping"; + for (auto eventIt = contents.begin(); eventIt != contents.end(); + ++eventIt) { + if (eventIt.key().isEmpty()) { + qCWarning(EPHEMERAL) + << "ReceiptEvent has an empty event id, skipping"; qCDebug(EPHEMERAL) << "ReceiptEvent content follows:\n" << contents; continue; } - const QJsonObject reads = eventIt.value().toObject() - .value("m.read"_ls).toObject(); + const QJsonObject reads = + eventIt.value().toObject().value("m.read"_ls).toObject(); QVector<Receipt> receipts; receipts.reserve(reads.size()); - for( auto userIt = reads.begin(); userIt != reads.end(); ++userIt ) - { + for (auto userIt = reads.begin(); userIt != reads.end(); ++userIt) { const QJsonObject user = userIt.value().toObject(); - receipts.push_back({userIt.key(), - fromJson<QDateTime>(user["ts"_ls])}); + receipts.push_back( + { userIt.key(), fromJson<QDateTime>(user["ts"_ls]) }); } - _eventsWithReceipts.push_back({eventIt.key(), std::move(receipts)}); + _eventsWithReceipts.push_back({ eventIt.key(), std::move(receipts) }); } } - diff --git a/lib/events/receiptevent.h b/lib/events/receiptevent.h index c15a01c2..fca38bba 100644 --- a/lib/events/receiptevent.h +++ b/lib/events/receiptevent.h @@ -13,42 +13,41 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #pragma once #include "event.h" -#include <QtCore/QVector> #include <QtCore/QDateTime> +#include <QtCore/QVector> -namespace QMatrixClient -{ - struct Receipt - { +namespace QMatrixClient { + struct Receipt { QString userId; QDateTime timestamp; }; - struct ReceiptsForEvent - { + struct ReceiptsForEvent { QString evtId; QVector<Receipt> receipts; }; using EventsWithReceipts = QVector<ReceiptsForEvent>; - class ReceiptEvent: public Event + class ReceiptEvent : public Event { public: - DEFINE_EVENT_TYPEID("m.receipt", ReceiptEvent) - explicit ReceiptEvent(const QJsonObject& obj); + DEFINE_EVENT_TYPEID("m.receipt", ReceiptEvent) + explicit ReceiptEvent(const QJsonObject& obj); - const EventsWithReceipts& eventsWithReceipts() const - { return _eventsWithReceipts; } + const EventsWithReceipts& eventsWithReceipts() const + { + return _eventsWithReceipts; + } private: - EventsWithReceipts _eventsWithReceipts; + EventsWithReceipts _eventsWithReceipts; }; REGISTER_EVENT_TYPE(ReceiptEvent) DEFINE_EVENTTYPE_ALIAS(Receipt, ReceiptEvent) -} // namespace QMatrixClient +} // namespace QMatrixClient diff --git a/lib/events/redactionevent.h b/lib/events/redactionevent.h index a72a8ff9..4187291c 100644 --- a/lib/events/redactionevent.h +++ b/lib/events/redactionevent.h @@ -13,28 +13,29 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #pragma once #include "roomevent.h" -namespace QMatrixClient -{ +namespace QMatrixClient { class RedactionEvent : public RoomEvent { public: - DEFINE_EVENT_TYPEID("m.room.redaction", RedactionEvent) + DEFINE_EVENT_TYPEID("m.room.redaction", RedactionEvent) - explicit RedactionEvent(const QJsonObject& obj) - : RoomEvent(typeId(), obj) - { } + explicit RedactionEvent(const QJsonObject& obj) + : RoomEvent(typeId(), obj) + { + } - QString redactedEvent() const - { return fullJson()["redacts"_ls].toString(); } - QString reason() const - { return contentJson()["reason"_ls].toString(); } + QString redactedEvent() const + { + return fullJson()["redacts"_ls].toString(); + } + QString reason() const { return contentJson()["reason"_ls].toString(); } }; REGISTER_EVENT_TYPE(RedactionEvent) DEFINE_EVENTTYPE_ALIAS(Redaction, RedactionEvent) diff --git a/lib/events/roomavatarevent.h b/lib/events/roomavatarevent.h index a43d3a85..69cd1f9d 100644 --- a/lib/events/roomavatarevent.h +++ b/lib/events/roomavatarevent.h @@ -13,29 +13,29 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #pragma once -#include "stateevent.h" #include "eventcontent.h" +#include "stateevent.h" -namespace QMatrixClient -{ - class RoomAvatarEvent: public StateEvent<EventContent::ImageContent> +namespace QMatrixClient { + class RoomAvatarEvent : public StateEvent<EventContent::ImageContent> { - // It's a bit of an overkill to use a full-fledged ImageContent - // because in reality m.room.avatar usually only has a single URL, - // without a thumbnail. But The Spec says there be thumbnails, and - // we follow The Spec. + // It's a bit of an overkill to use a full-fledged ImageContent + // because in reality m.room.avatar usually only has a single URL, + // without a thumbnail. But The Spec says there be thumbnails, and + // we follow The Spec. public: - DEFINE_EVENT_TYPEID("m.room.avatar", RoomAvatarEvent) - explicit RoomAvatarEvent(const QJsonObject& obj) - : StateEvent(typeId(), obj) - { } - QUrl url() const { return content().url; } + DEFINE_EVENT_TYPEID("m.room.avatar", RoomAvatarEvent) + explicit RoomAvatarEvent(const QJsonObject& obj) + : StateEvent(typeId(), obj) + { + } + QUrl url() const { return content().url; } }; REGISTER_EVENT_TYPE(RoomAvatarEvent) DEFINE_EVENTTYPE_ALIAS(RoomAvatar, RoomAvatarEvent) -} // namespace QMatrixClient +} // namespace QMatrixClient diff --git a/lib/events/roomcreateevent.cpp b/lib/events/roomcreateevent.cpp index 8fd0f1de..cb575f24 100644 --- a/lib/events/roomcreateevent.cpp +++ b/lib/events/roomcreateevent.cpp @@ -1,20 +1,20 @@ /****************************************************************************** -* Copyright (C) 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 -*/ + * Copyright (C) 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 + */ #include "roomcreateevent.h" @@ -33,10 +33,8 @@ QString RoomCreateEvent::version() const RoomCreateEvent::Predecessor RoomCreateEvent::predecessor() const { const auto predJson = contentJson()["predecessor"_ls].toObject(); - return { - fromJson<QString>(predJson["room_id"_ls]), - fromJson<QString>(predJson["event_id"_ls]) - }; + return { fromJson<QString>(predJson["room_id"_ls]), + fromJson<QString>(predJson["event_id"_ls]) }; } bool RoomCreateEvent::isUpgrade() const diff --git a/lib/events/roomcreateevent.h b/lib/events/roomcreateevent.h index 0a8f27cc..fbfb33ca 100644 --- a/lib/events/roomcreateevent.h +++ b/lib/events/roomcreateevent.h @@ -1,49 +1,46 @@ /****************************************************************************** -* Copyright (C) 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 -*/ + * Copyright (C) 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 + */ #pragma once #include "stateevent.h" -namespace QMatrixClient -{ +namespace QMatrixClient { class RoomCreateEvent : public StateEventBase { public: - DEFINE_EVENT_TYPEID("m.room.create", RoomCreateEvent) + DEFINE_EVENT_TYPEID("m.room.create", RoomCreateEvent) - explicit RoomCreateEvent() - : StateEventBase(typeId(), matrixTypeId()) - { } - explicit RoomCreateEvent(const QJsonObject& obj) - : StateEventBase(typeId(), obj) - { } + explicit RoomCreateEvent() : StateEventBase(typeId(), matrixTypeId()) {} + explicit RoomCreateEvent(const QJsonObject& obj) + : StateEventBase(typeId(), obj) + { + } - struct Predecessor - { - QString roomId; - QString eventId; - }; + struct Predecessor { + QString roomId; + QString eventId; + }; - bool isFederated() const; - QString version() const; - Predecessor predecessor() const; - bool isUpgrade() const; + bool isFederated() const; + QString version() const; + Predecessor predecessor() const; + bool isUpgrade() const; }; REGISTER_EVENT_TYPE(RoomCreateEvent) } diff --git a/lib/events/roomevent.cpp b/lib/events/roomevent.cpp index 3d03509f..221a3a61 100644 --- a/lib/events/roomevent.cpp +++ b/lib/events/roomevent.cpp @@ -1,26 +1,26 @@ /****************************************************************************** -* Copyright (C) 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 -*/ + * Copyright (C) 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 + */ #include "roomevent.h" -#include "redactionevent.h" #include "converters.h" #include "logging.h" +#include "redactionevent.h" using namespace QMatrixClient; @@ -30,15 +30,14 @@ using namespace QMatrixClient; RoomEvent::RoomEvent(Type type, event_mtype_t matrixType, const QJsonObject& contentJson) : Event(type, matrixType, contentJson) -{ } +{ +} -RoomEvent::RoomEvent(Type type, const QJsonObject& json) - : Event(type, json) +RoomEvent::RoomEvent(Type type, const QJsonObject& json) : Event(type, json) { const auto unsignedData = json[UnsignedKeyL].toObject(); const auto redaction = unsignedData[RedactedCauseKeyL]; - if (redaction.isObject()) - { + if (redaction.isObject()) { _redactedBecause = makeEvent<RedactionEvent>(redaction.toObject()); return; } @@ -46,14 +45,12 @@ RoomEvent::RoomEvent(Type type, const QJsonObject& json) RoomEvent::~RoomEvent() = default; // Let the smart pointer do its job -QString RoomEvent::id() const -{ - return fullJson()[EventIdKeyL].toString(); -} +QString RoomEvent::id() const { return fullJson()[EventIdKeyL].toString(); } QDateTime RoomEvent::timestamp() const { - return QMatrixClient::fromJson<QDateTime>(fullJson()["origin_server_ts"_ls]); + return QMatrixClient::fromJson<QDateTime>( + fullJson()["origin_server_ts"_ls]); } QString RoomEvent::roomId() const @@ -68,7 +65,7 @@ QString RoomEvent::senderId() const QString RoomEvent::redactionReason() const { - return isRedacted() ? _redactedBecause->reason() : QString{}; + return isRedacted() ? _redactedBecause->reason() : QString {}; } QString RoomEvent::transactionId() const @@ -91,7 +88,8 @@ void RoomEvent::setTransactionId(const QString& txnId) void RoomEvent::addId(const QString& newId) { - Q_ASSERT(id().isEmpty()); Q_ASSERT(!newId.isEmpty()); + Q_ASSERT(id().isEmpty()); + Q_ASSERT(!newId.isEmpty()); editJson().insert(EventIdKey, newId); qCDebug(EVENTS) << "Event txnId -> id:" << transactionId() << "->" << id(); Q_ASSERT(id() == newId); @@ -110,7 +108,8 @@ CallEventBase::CallEventBase(Type type, event_mtype_t matrixType, const QJsonObject& contentJson) : RoomEvent(type, matrixType, makeCallContentJson(callId, version, contentJson)) -{ } +{ +} CallEventBase::CallEventBase(Event::Type type, const QJsonObject& json) : RoomEvent(type, json) diff --git a/lib/events/roomevent.h b/lib/events/roomevent.h index ce96174e..746e9173 100644 --- a/lib/events/roomevent.h +++ b/lib/events/roomevent.h @@ -1,20 +1,20 @@ /****************************************************************************** -* Copyright (C) 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 -*/ + * Copyright (C) 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 + */ #pragma once @@ -22,84 +22,84 @@ #include <QtCore/QDateTime> -namespace QMatrixClient -{ +namespace QMatrixClient { class RedactionEvent; /** This class corresponds to m.room.* events */ class RoomEvent : public Event { - Q_GADGET - Q_PROPERTY(QString id READ id) - Q_PROPERTY(QDateTime timestamp READ timestamp CONSTANT) - Q_PROPERTY(QString roomId READ roomId CONSTANT) - Q_PROPERTY(QString senderId READ senderId CONSTANT) - Q_PROPERTY(QString redactionReason READ redactionReason) - Q_PROPERTY(bool isRedacted READ isRedacted) - Q_PROPERTY(QString transactionId READ transactionId WRITE setTransactionId) + Q_GADGET + Q_PROPERTY(QString id READ id) + Q_PROPERTY(QDateTime timestamp READ timestamp CONSTANT) + Q_PROPERTY(QString roomId READ roomId CONSTANT) + Q_PROPERTY(QString senderId READ senderId CONSTANT) + Q_PROPERTY(QString redactionReason READ redactionReason) + Q_PROPERTY(bool isRedacted READ isRedacted) + Q_PROPERTY( + QString transactionId READ transactionId WRITE setTransactionId) public: - using factory_t = EventFactory<RoomEvent>; + using factory_t = EventFactory<RoomEvent>; - // RedactionEvent is an incomplete type here so we cannot inline - // constructors and destructors and we cannot use 'using'. - RoomEvent(Type type, event_mtype_t matrixType, - const QJsonObject& contentJson = {}); - RoomEvent(Type type, const QJsonObject& json); - ~RoomEvent() override; + // RedactionEvent is an incomplete type here so we cannot inline + // constructors and destructors and we cannot use 'using'. + RoomEvent(Type type, event_mtype_t matrixType, + const QJsonObject& contentJson = {}); + RoomEvent(Type type, const QJsonObject& json); + ~RoomEvent() override; - QString id() const; - QDateTime timestamp() const; - QString roomId() const; - QString senderId() const; - bool isRedacted() const { return bool(_redactedBecause); } - const event_ptr_tt<RedactionEvent>& redactedBecause() const - { - return _redactedBecause; - } - QString redactionReason() const; - QString transactionId() const; - QString stateKey() const; + QString id() const; + QDateTime timestamp() const; + QString roomId() const; + QString senderId() const; + bool isRedacted() const { return bool(_redactedBecause); } + const event_ptr_tt<RedactionEvent>& redactedBecause() const + { + return _redactedBecause; + } + QString redactionReason() const; + QString transactionId() const; + QString stateKey() const; - /** - * Sets the transaction id for locally created events. This should be - * done before the event is exposed to any code using the respective - * Q_PROPERTY. - * - * \param txnId - transaction id, normally obtained from - * Connection::generateTxnId() - */ - void setTransactionId(const QString& txnId); + /** + * Sets the transaction id for locally created events. This should be + * done before the event is exposed to any code using the respective + * Q_PROPERTY. + * + * \param txnId - transaction id, normally obtained from + * Connection::generateTxnId() + */ + void setTransactionId(const QString& txnId); - /** - * Sets event id for locally created events - * - * When a new event is created locally, it has no server id yet. - * This function allows to add the id once the confirmation from - * the server is received. There should be no id set previously - * in the event. It's the responsibility of the code calling addId() - * to notify clients that use Q_PROPERTY(id) about its change - */ - void addId(const QString& newId); + /** + * Sets event id for locally created events + * + * When a new event is created locally, it has no server id yet. + * This function allows to add the id once the confirmation from + * the server is received. There should be no id set previously + * in the event. It's the responsibility of the code calling addId() + * to notify clients that use Q_PROPERTY(id) about its change + */ + void addId(const QString& newId); private: - event_ptr_tt<RedactionEvent> _redactedBecause; + event_ptr_tt<RedactionEvent> _redactedBecause; }; using RoomEventPtr = event_ptr_tt<RoomEvent>; using RoomEvents = EventsArray<RoomEvent>; using RoomEventsRange = Range<RoomEvents>; - class CallEventBase: public RoomEvent + class CallEventBase : public RoomEvent { public: - CallEventBase(Type type, event_mtype_t matrixType, - const QString& callId, int version, - const QJsonObject& contentJson = {}); - CallEventBase(Type type, const QJsonObject& json); - ~CallEventBase() override = default; - bool isCallEvent() const override { return true; } + CallEventBase(Type type, event_mtype_t matrixType, + const QString& callId, int version, + const QJsonObject& contentJson = {}); + CallEventBase(Type type, const QJsonObject& json); + ~CallEventBase() override = default; + bool isCallEvent() const override { return true; } - QString callId() const { return content<QString>("call_id"_ls); } - int version() const { return content<int>("version"_ls); } + QString callId() const { return content<QString>("call_id"_ls); } + int version() const { return content<int>("version"_ls); } }; } // namespace QMatrixClient Q_DECLARE_METATYPE(QMatrixClient::RoomEvent*) diff --git a/lib/events/roommemberevent.cpp b/lib/events/roommemberevent.cpp index a5ac3c5f..53203873 100644 --- a/lib/events/roommemberevent.cpp +++ b/lib/events/roommemberevent.cpp @@ -13,7 +13,7 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "roommemberevent.h" @@ -23,21 +23,18 @@ #include <array> -static const std::array<QString, 5> membershipStrings = { { - QStringLiteral("invite"), QStringLiteral("join"), - QStringLiteral("knock"), QStringLiteral("leave"), - QStringLiteral("ban") -} }; +static const std::array<QString, 5> membershipStrings = { + { QStringLiteral("invite"), QStringLiteral("join"), QStringLiteral("knock"), + QStringLiteral("leave"), QStringLiteral("ban") } +}; namespace QMatrixClient { - template <> - struct JsonConverter<MembershipType> - { + template <> struct JsonConverter<MembershipType> { static MembershipType load(const QJsonValue& jv) { const auto& membershipString = jv.toString(); for (auto it = membershipStrings.begin(); - it != membershipStrings.end(); ++it) + it != membershipStrings.end(); ++it) if (membershipString == *it) return MembershipType(it - membershipStrings.begin()); @@ -50,17 +47,18 @@ namespace QMatrixClient { using namespace QMatrixClient; MemberEventContent::MemberEventContent(const QJsonObject& json) - : membership(fromJson<MembershipType>(json["membership"_ls])) - , isDirect(json["is_direct"_ls].toBool()) - , displayName(json["displayname"_ls].toString()) - , avatarUrl(json["avatar_url"_ls].toString()) -{ } + : membership(fromJson<MembershipType>(json["membership"_ls])), + isDirect(json["is_direct"_ls].toBool()), + displayName(json["displayname"_ls].toString()), + avatarUrl(json["avatar_url"_ls].toString()) +{ +} void MemberEventContent::fillJson(QJsonObject* o) const { Q_ASSERT(o); Q_ASSERT_X(membership != MembershipType::Undefined, __FUNCTION__, - "The key 'membership' must be explicit in MemberEventContent"); + "The key 'membership' must be explicit in MemberEventContent"); if (membership != MembershipType::Undefined) o->insert(QStringLiteral("membership"), membershipStrings[membership]); o->insert(QStringLiteral("displayname"), displayName); @@ -70,21 +68,21 @@ void MemberEventContent::fillJson(QJsonObject* o) const bool RoomMemberEvent::isInvite() const { - return membership() == MembershipType::Invite && - (!prevContent() || prevContent()->membership != membership()); + return membership() == MembershipType::Invite + && (!prevContent() || prevContent()->membership != membership()); } bool RoomMemberEvent::isJoin() const { - return membership() == MembershipType::Join && - (!prevContent() || prevContent()->membership != membership()); + return membership() == MembershipType::Join + && (!prevContent() || prevContent()->membership != membership()); } bool RoomMemberEvent::isLeave() const { - return membership() == MembershipType::Leave && - prevContent() && prevContent()->membership != membership() && - prevContent()->membership != MembershipType::Ban; + return membership() == MembershipType::Leave && prevContent() + && prevContent()->membership != membership() + && prevContent()->membership != MembershipType::Ban; } bool RoomMemberEvent::isRename() const diff --git a/lib/events/roommemberevent.h b/lib/events/roommemberevent.h index b8224033..55f419d8 100644 --- a/lib/events/roommemberevent.h +++ b/lib/events/roommemberevent.h @@ -13,94 +13,100 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #pragma once -#include "stateevent.h" #include "eventcontent.h" +#include "stateevent.h" -namespace QMatrixClient -{ - class MemberEventContent: public EventContent::Base +namespace QMatrixClient { + class MemberEventContent : public EventContent::Base { public: - enum MembershipType : size_t { Invite = 0, Join, Knock, Leave, Ban, - Undefined }; + enum MembershipType : size_t { + Invite = 0, + Join, + Knock, + Leave, + Ban, + Undefined + }; - explicit MemberEventContent(MembershipType mt = Join) - : membership(mt) - { } - explicit MemberEventContent(const QJsonObject& json); + explicit MemberEventContent(MembershipType mt = Join) : membership(mt) + { + } + explicit MemberEventContent(const QJsonObject& json); - MembershipType membership; - bool isDirect = false; - QString displayName; - QUrl avatarUrl; + MembershipType membership; + bool isDirect = false; + QString displayName; + QUrl avatarUrl; protected: - void fillJson(QJsonObject* o) const override; + void fillJson(QJsonObject* o) const override; }; using MembershipType = MemberEventContent::MembershipType; - class RoomMemberEvent: public StateEvent<MemberEventContent> + class RoomMemberEvent : public StateEvent<MemberEventContent> { - Q_GADGET + Q_GADGET public: - DEFINE_EVENT_TYPEID("m.room.member", RoomMemberEvent) + DEFINE_EVENT_TYPEID("m.room.member", RoomMemberEvent) - using MembershipType = MemberEventContent::MembershipType; + using MembershipType = MemberEventContent::MembershipType; - explicit RoomMemberEvent(const QJsonObject& obj) - : StateEvent(typeId(), obj) - { } - RoomMemberEvent(MemberEventContent&& c) - : StateEvent(typeId(), matrixTypeId(), c) - { } + explicit RoomMemberEvent(const QJsonObject& obj) + : StateEvent(typeId(), obj) + { + } + RoomMemberEvent(MemberEventContent&& c) + : StateEvent(typeId(), matrixTypeId(), c) + { + } - /// A special constructor to create unknown RoomMemberEvents - /** - * This is needed in order to use RoomMemberEvent as a "base event - * class" in cases like GetMembersByRoomJob when RoomMemberEvents - * (rather than RoomEvents or StateEvents) are resolved from JSON. - * For such cases loadEvent<> requires an underlying class to be - * constructible with unknownTypeId() instead of its genuine id. - * Don't use it directly. - * \sa GetMembersByRoomJob, loadEvent, unknownTypeId - */ - RoomMemberEvent(Type type, const QJsonObject& fullJson) - : StateEvent(type, fullJson) - { } + /// A special constructor to create unknown RoomMemberEvents + /** + * This is needed in order to use RoomMemberEvent as a "base event + * class" in cases like GetMembersByRoomJob when RoomMemberEvents + * (rather than RoomEvents or StateEvents) are resolved from JSON. + * For such cases loadEvent<> requires an underlying class to be + * constructible with unknownTypeId() instead of its genuine id. + * Don't use it directly. + * \sa GetMembersByRoomJob, loadEvent, unknownTypeId + */ + RoomMemberEvent(Type type, const QJsonObject& fullJson) + : StateEvent(type, fullJson) + { + } - MembershipType membership() const { return content().membership; } - QString userId() const - { return fullJson()["state_key"_ls].toString(); } - bool isDirect() const { return content().isDirect; } - QString displayName() const { return content().displayName; } - QUrl avatarUrl() const { return content().avatarUrl; } - bool isInvite() const; - bool isJoin() const; - bool isLeave() const; - bool isRename() const; - bool isAvatarUpdate() const; + MembershipType membership() const { return content().membership; } + QString userId() const { return fullJson()["state_key"_ls].toString(); } + bool isDirect() const { return content().isDirect; } + QString displayName() const { return content().displayName; } + QUrl avatarUrl() const { return content().avatarUrl; } + bool isInvite() const; + bool isJoin() const; + bool isLeave() const; + bool isRename() const; + bool isAvatarUpdate() const; private: - REGISTER_ENUM(MembershipType) + REGISTER_ENUM(MembershipType) }; - template <> - class EventFactory<RoomMemberEvent> + template <> class EventFactory<RoomMemberEvent> { public: - static event_ptr_tt<RoomMemberEvent> make(const QJsonObject& json, - const QString&) - { - return makeEvent<RoomMemberEvent>(json); - } + static event_ptr_tt<RoomMemberEvent> make(const QJsonObject& json, + const QString&) + { + return makeEvent<RoomMemberEvent>(json); + } }; REGISTER_EVENT_TYPE(RoomMemberEvent) DEFINE_EVENTTYPE_ALIAS(RoomMember, RoomMemberEvent) -} // namespace QMatrixClient +} // namespace QMatrixClient diff --git a/lib/events/roommessageevent.cpp b/lib/events/roommessageevent.cpp index 8f4e0ebc..0af02eb0 100644 --- a/lib/events/roommessageevent.cpp +++ b/lib/events/roommessageevent.cpp @@ -13,15 +13,15 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "roommessageevent.h" #include "logging.h" -#include <QtCore/QMimeDatabase> #include <QtCore/QFileInfo> +#include <QtCore/QMimeDatabase> #include <QtGui/QImageReader> #include <QtMultimedia/QMediaResource> @@ -40,41 +40,40 @@ static const auto NoticeTypeKey = "m.notice"; static const auto HtmlContentTypeId = QStringLiteral("org.matrix.custom.html"); -template <typename ContentT> -TypedBase* make(const QJsonObject& json) +template <typename ContentT> TypedBase* make(const QJsonObject& json) { return new ContentT(json); } -template <> -TypedBase* make<TextContent>(const QJsonObject& json) +template <> TypedBase* make<TextContent>(const QJsonObject& json) { return json.contains(FormattedBodyKey) || json.contains(RelatesToKey) - ? new TextContent(json) : nullptr; + ? new TextContent(json) + : nullptr; } -struct MsgTypeDesc -{ +struct MsgTypeDesc { QString matrixType; MsgType enumType; TypedBase* (*maker)(const QJsonObject&); }; -const std::vector<MsgTypeDesc> msgTypes = - { { TextTypeKey, MsgType::Text, make<TextContent> } - , { QStringLiteral("m.emote"), MsgType::Emote, make<TextContent> } - , { NoticeTypeKey, MsgType::Notice, make<TextContent> } - , { QStringLiteral("m.image"), MsgType::Image, make<ImageContent> } - , { QStringLiteral("m.file"), MsgType::File, make<FileContent> } - , { QStringLiteral("m.location"), MsgType::Location, make<LocationContent> } - , { QStringLiteral("m.video"), MsgType::Video, make<VideoContent> } - , { QStringLiteral("m.audio"), MsgType::Audio, make<AudioContent> } - }; +const std::vector<MsgTypeDesc> msgTypes = { + { TextTypeKey, MsgType::Text, make<TextContent> }, + { QStringLiteral("m.emote"), MsgType::Emote, make<TextContent> }, + { NoticeTypeKey, MsgType::Notice, make<TextContent> }, + { QStringLiteral("m.image"), MsgType::Image, make<ImageContent> }, + { QStringLiteral("m.file"), MsgType::File, make<FileContent> }, + { QStringLiteral("m.location"), MsgType::Location, make<LocationContent> }, + { QStringLiteral("m.video"), MsgType::Video, make<VideoContent> }, + { QStringLiteral("m.audio"), MsgType::Audio, make<AudioContent> } +}; QString msgTypeToJson(MsgType enumType) { - auto it = std::find_if(msgTypes.begin(), msgTypes.end(), - [=](const MsgTypeDesc& mtd) { return mtd.enumType == enumType; }); + auto it = std::find_if( + msgTypes.begin(), msgTypes.end(), + [=](const MsgTypeDesc& mtd) { return mtd.enumType == enumType; }); if (it != msgTypes.end()) return it->matrixType; @@ -84,7 +83,9 @@ QString msgTypeToJson(MsgType enumType) MsgType jsonToMsgType(const QString& matrixType) { auto it = std::find_if(msgTypes.begin(), msgTypes.end(), - [=](const MsgTypeDesc& mtd) { return mtd.matrixType == matrixType; }); + [=](const MsgTypeDesc& mtd) { + return mtd.matrixType == matrixType; + }); if (it != msgTypes.end()) return it->enumType; @@ -92,12 +93,12 @@ MsgType jsonToMsgType(const QString& matrixType) } QJsonObject RoomMessageEvent::assembleContentJson(const QString& plainBody, - const QString& jsonMsgType, TypedBase* content) + const QString& jsonMsgType, + TypedBase* content) { auto json = content ? content->toJson() : QJsonObject(); - if (jsonMsgType != TextTypeKey && jsonMsgType != NoticeTypeKey && - json.contains(RelatesToKey)) - { + if (jsonMsgType != TextTypeKey && jsonMsgType != NoticeTypeKey + && json.contains(RelatesToKey)) { json.remove(RelatesToKey); qCWarning(EVENTS) << RelatesToKey << "cannot be used in" << jsonMsgType << "messages; the relation has been stripped off"; @@ -108,24 +109,26 @@ QJsonObject RoomMessageEvent::assembleContentJson(const QString& plainBody, } RoomMessageEvent::RoomMessageEvent(const QString& plainBody, - const QString& jsonMsgType, TypedBase* content) + const QString& jsonMsgType, + TypedBase* content) : RoomEvent(typeId(), matrixTypeId(), - assembleContentJson(plainBody, jsonMsgType, content)) - , _content(content) -{ } + assembleContentJson(plainBody, jsonMsgType, content)), + _content(content) +{ +} -RoomMessageEvent::RoomMessageEvent(const QString& plainBody, - MsgType msgType, TypedBase* content) +RoomMessageEvent::RoomMessageEvent(const QString& plainBody, MsgType msgType, + TypedBase* content) : RoomMessageEvent(plainBody, msgTypeToJson(msgType), content) -{ } +{ +} TypedBase* contentFromFile(const QFileInfo& file, bool asGenericFile) { auto filePath = file.absoluteFilePath(); auto localUrl = QUrl::fromLocalFile(filePath); auto mimeType = QMimeDatabase().mimeTypeForFile(file); - if (!asGenericFile) - { + if (!asGenericFile) { auto mimeTypeName = mimeType.name(); if (mimeTypeName.startsWith("image/")) return new ImageContent(localUrl, file.size(), mimeType, @@ -147,11 +150,13 @@ TypedBase* contentFromFile(const QFileInfo& file, bool asGenericFile) } RoomMessageEvent::RoomMessageEvent(const QString& plainBody, - const QFileInfo& file, bool asGenericFile) + const QFileInfo& file, bool asGenericFile) : RoomMessageEvent(plainBody, - asGenericFile ? QStringLiteral("m.file") : rawMsgTypeForFile(file), - contentFromFile(file, asGenericFile)) -{ } + asGenericFile ? QStringLiteral("m.file") + : rawMsgTypeForFile(file), + contentFromFile(file, asGenericFile)) +{ +} RoomMessageEvent::RoomMessageEvent(const QJsonObject& obj) : RoomEvent(typeId(), obj), _content(nullptr) @@ -159,26 +164,21 @@ RoomMessageEvent::RoomMessageEvent(const QJsonObject& obj) if (isRedacted()) return; const QJsonObject content = contentJson(); - if ( content.contains(MsgTypeKey) && content.contains(BodyKey) ) - { + if (content.contains(MsgTypeKey) && content.contains(BodyKey)) { auto msgtype = content[MsgTypeKey].toString(); bool msgTypeFound = false; - for (const auto& mt: msgTypes) - if (mt.matrixType == msgtype) - { + for (const auto& mt : msgTypes) + if (mt.matrixType == msgtype) { _content.reset(mt.maker(content)); msgTypeFound = true; } - if (!msgTypeFound) - { + if (!msgTypeFound) { qCWarning(EVENTS) << "RoomMessageEvent: unknown msg_type," << " full content dump follows"; qCWarning(EVENTS) << formatJson << content; } - } - else - { + } else { qCWarning(EVENTS) << "No body or msgtype in room message event"; qCWarning(EVENTS) << formatJson << obj; } @@ -208,9 +208,9 @@ QMimeType RoomMessageEvent::mimeType() const bool RoomMessageEvent::hasTextContent() const { - return !content() || - (msgtype() == MsgType::Text || msgtype() == MsgType::Emote || - msgtype() == MsgType::Notice); + return !content() + || (msgtype() == MsgType::Text || msgtype() == MsgType::Emote + || msgtype() == MsgType::Notice); } bool RoomMessageEvent::hasFileContent() const @@ -226,10 +226,11 @@ bool RoomMessageEvent::hasThumbnail() const QString rawMsgTypeForMimeType(const QMimeType& mimeType) { auto name = mimeType.name(); - return name.startsWith("image/") ? QStringLiteral("m.image") : - name.startsWith("video/") ? QStringLiteral("m.video") : - name.startsWith("audio/") ? QStringLiteral("m.audio") : - QStringLiteral("m.file"); + return name.startsWith("image/") ? QStringLiteral("m.image") + : name.startsWith("video/") + ? QStringLiteral("m.video") + : name.startsWith("audio/") ? QStringLiteral("m.audio") + : QStringLiteral("m.file"); } QString RoomMessageEvent::rawMsgTypeForUrl(const QUrl& url) @@ -244,8 +245,9 @@ QString RoomMessageEvent::rawMsgTypeForFile(const QFileInfo& fi) TextContent::TextContent(const QString& text, const QString& contentType, Omittable<RelatesTo> relatesTo) - : mimeType(QMimeDatabase().mimeTypeForName(contentType)), body(text) - , relatesTo(std::move(relatesTo)) + : mimeType(QMimeDatabase().mimeTypeForName(contentType)), + body(text), + relatesTo(std::move(relatesTo)) { if (contentType == HtmlContentTypeId) mimeType = QMimeDatabase().mimeTypeForName("text/html"); @@ -259,8 +261,7 @@ TextContent::TextContent(const QJsonObject& json) // Special-casing the custom matrix.org's (actually, Riot's) way // of sending HTML messages. - if (json["format"_ls].toString() == HtmlContentTypeId) - { + if (json["format"_ls].toString() == HtmlContentTypeId) { mimeType = HtmlMimeType; body = json[FormattedBodyKey].toString(); } else { @@ -269,8 +270,10 @@ TextContent::TextContent(const QJsonObject& json) mimeType = PlainTextMimeType; body = json[BodyKey].toString(); } - const auto replyJson = json[RelatesToKey].toObject() - .value(RelatesTo::ReplyTypeId()).toObject(); + const auto replyJson = json[RelatesToKey] + .toObject() + .value(RelatesTo::ReplyTypeId()) + .toObject(); if (!replyJson.isEmpty()) relatesTo = replyTo(fromJson<QString>(replyJson[EventIdKeyL])); } @@ -278,26 +281,27 @@ TextContent::TextContent(const QJsonObject& json) void TextContent::fillJson(QJsonObject* json) const { Q_ASSERT(json); - if (mimeType.inherits("text/html")) - { + if (mimeType.inherits("text/html")) { json->insert(QStringLiteral("format"), HtmlContentTypeId); json->insert(QStringLiteral("formatted_body"), body); } if (!relatesTo.omitted()) json->insert(QStringLiteral("m.relates_to"), - QJsonObject { { relatesTo->type, relatesTo->eventId } }); + QJsonObject { { relatesTo->type, relatesTo->eventId } }); } LocationContent::LocationContent(const QString& geoUri, const Thumbnail& thumbnail) : geoUri(geoUri), thumbnail(thumbnail) -{ } +{ +} LocationContent::LocationContent(const QJsonObject& json) - : TypedBase(json) - , geoUri(json["geo_uri"_ls].toString()) - , thumbnail(json["info"_ls].toObject()) -{ } + : TypedBase(json), + geoUri(json["geo_uri"_ls].toString()), + thumbnail(json["info"_ls].toObject()) +{ +} QMimeType LocationContent::type() const { diff --git a/lib/events/roommessageevent.h b/lib/events/roommessageevent.h index c2e075eb..bd1b7c83 100644 --- a/lib/events/roommessageevent.h +++ b/lib/events/roommessageevent.h @@ -13,88 +13,94 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #pragma once -#include "roomevent.h" #include "eventcontent.h" +#include "roomevent.h" class QFileInfo; -namespace QMatrixClient -{ +namespace QMatrixClient { namespace MessageEventContent = EventContent; // Back-compatibility /** * The event class corresponding to m.room.message events */ - class RoomMessageEvent: public RoomEvent + class RoomMessageEvent : public RoomEvent { - Q_GADGET - Q_PROPERTY(QString msgType READ rawMsgtype CONSTANT) - Q_PROPERTY(QString plainBody READ plainBody CONSTANT) - Q_PROPERTY(QMimeType mimeType READ mimeType STORED false CONSTANT) - Q_PROPERTY(EventContent::TypedBase* content READ content CONSTANT) + Q_GADGET + Q_PROPERTY(QString msgType READ rawMsgtype CONSTANT) + Q_PROPERTY(QString plainBody READ plainBody CONSTANT) + Q_PROPERTY(QMimeType mimeType READ mimeType STORED false CONSTANT) + Q_PROPERTY(EventContent::TypedBase* content READ content CONSTANT) public: - DEFINE_EVENT_TYPEID("m.room.message", RoomMessageEvent) + DEFINE_EVENT_TYPEID("m.room.message", RoomMessageEvent) + + enum class MsgType { + Text, + Emote, + Notice, + Image, + File, + Location, + Video, + Audio, + Unknown + }; - enum class MsgType - { - Text, Emote, Notice, Image, File, Location, Video, Audio, Unknown - }; - - RoomMessageEvent(const QString& plainBody, - const QString& jsonMsgType, - EventContent::TypedBase* content = nullptr); - explicit RoomMessageEvent(const QString& plainBody, - MsgType msgType = MsgType::Text, - EventContent::TypedBase* content = nullptr); - explicit RoomMessageEvent(const QString& plainBody, - const QFileInfo& file, - bool asGenericFile = false); - explicit RoomMessageEvent(const QJsonObject& obj); - - MsgType msgtype() const; - QString rawMsgtype() const; - QString plainBody() const; - EventContent::TypedBase* content() const - { return _content.data(); } - template <typename VisitorT> - void editContent(VisitorT visitor) - { - visitor(*_content); - editJson()[ContentKeyL] = + RoomMessageEvent(const QString& plainBody, const QString& jsonMsgType, + EventContent::TypedBase* content = nullptr); + explicit RoomMessageEvent(const QString& plainBody, + MsgType msgType = MsgType::Text, + EventContent::TypedBase* content = nullptr); + explicit RoomMessageEvent(const QString& plainBody, + const QFileInfo& file, + bool asGenericFile = false); + explicit RoomMessageEvent(const QJsonObject& obj); + + MsgType msgtype() const; + QString rawMsgtype() const; + QString plainBody() const; + EventContent::TypedBase* content() const { return _content.data(); } + template <typename VisitorT> void editContent(VisitorT visitor) + { + visitor(*_content); + editJson()[ContentKeyL] = assembleContentJson(plainBody(), rawMsgtype(), content()); - } - QMimeType mimeType() const; - bool hasTextContent() const; - bool hasFileContent() const; - bool hasThumbnail() const; + } + QMimeType mimeType() const; + bool hasTextContent() const; + bool hasFileContent() const; + bool hasThumbnail() const; - static QString rawMsgTypeForUrl(const QUrl& url); - static QString rawMsgTypeForFile(const QFileInfo& fi); + static QString rawMsgTypeForUrl(const QUrl& url); + static QString rawMsgTypeForFile(const QFileInfo& fi); private: - QScopedPointer<EventContent::TypedBase> _content; + QScopedPointer<EventContent::TypedBase> _content; - static QJsonObject assembleContentJson(const QString& plainBody, - const QString& jsonMsgType, EventContent::TypedBase* content); + static QJsonObject + assembleContentJson(const QString& plainBody, + const QString& jsonMsgType, + EventContent::TypedBase* content); - REGISTER_ENUM(MsgType) + REGISTER_ENUM(MsgType) }; REGISTER_EVENT_TYPE(RoomMessageEvent) DEFINE_EVENTTYPE_ALIAS(RoomMessage, RoomMessageEvent) using MessageEventType = RoomMessageEvent::MsgType; - namespace EventContent - { + namespace EventContent { // Additional event content types - struct RelatesTo - { - static constexpr const char* ReplyTypeId() { return "m.in_reply_to"; } + struct RelatesTo { + static constexpr const char* ReplyTypeId() + { + return "m.in_reply_to"; + } QString type; // The only supported relation so far QString eventId; }; @@ -109,21 +115,21 @@ namespace QMatrixClient * Available fields: mimeType, body. The body can be either rich text * or plain text, depending on what mimeType specifies. */ - class TextContent: public TypedBase + class TextContent : public TypedBase { public: - TextContent(const QString& text, const QString& contentType, - Omittable<RelatesTo> relatesTo = none); - explicit TextContent(const QJsonObject& json); + TextContent(const QString& text, const QString& contentType, + Omittable<RelatesTo> relatesTo = none); + explicit TextContent(const QJsonObject& json); - QMimeType type() const override { return mimeType; } + QMimeType type() const override { return mimeType; } - QMimeType mimeType; - QString body; - Omittable<RelatesTo> relatesTo; + QMimeType mimeType; + QString body; + Omittable<RelatesTo> relatesTo; protected: - void fillJson(QJsonObject* json) const override; + void fillJson(QJsonObject* json) const override; }; /** @@ -139,47 +145,47 @@ namespace QMatrixClient * - thumbnail.mimeType * - thumbnail.imageSize */ - class LocationContent: public TypedBase + class LocationContent : public TypedBase { public: - LocationContent(const QString& geoUri, - const Thumbnail& thumbnail = {}); - explicit LocationContent(const QJsonObject& json); + LocationContent(const QString& geoUri, + const Thumbnail& thumbnail = {}); + explicit LocationContent(const QJsonObject& json); - QMimeType type() const override; + QMimeType type() const override; public: - QString geoUri; - Thumbnail thumbnail; + QString geoUri; + Thumbnail thumbnail; protected: - void fillJson(QJsonObject* o) const override; + void fillJson(QJsonObject* o) const override; }; /** * A base class for info types that include duration: audio and video */ - template <typename ContentT> - class PlayableContent : public ContentT + template <typename ContentT> class PlayableContent : public ContentT { public: - using ContentT::ContentT; - PlayableContent(const QJsonObject& json) - : ContentT(json) - , duration(ContentT::originalInfoJson["duration"_ls].toInt()) - { } + using ContentT::ContentT; + PlayableContent(const QJsonObject& json) + : ContentT(json), + duration(ContentT::originalInfoJson["duration"_ls].toInt()) + { + } protected: - void fillJson(QJsonObject* json) const override - { - ContentT::fillJson(json); - auto infoJson = json->take("info"_ls).toObject(); - infoJson.insert(QStringLiteral("duration"), duration); - json->insert(QStringLiteral("info"), infoJson); - } + void fillJson(QJsonObject* json) const override + { + ContentT::fillJson(json); + auto infoJson = json->take("info"_ls).toObject(); + infoJson.insert(QStringLiteral("duration"), duration); + json->insert(QStringLiteral("info"), infoJson); + } public: - int duration; + int duration; }; /** @@ -201,7 +207,8 @@ namespace QMatrixClient * - mimeType * - imageSize */ - using VideoContent = PlayableContent<UrlWithThumbnailContent<ImageInfo>>; + using VideoContent = + PlayableContent<UrlWithThumbnailContent<ImageInfo>>; /** * Content class for m.audio @@ -216,5 +223,5 @@ namespace QMatrixClient * - duration */ using AudioContent = PlayableContent<UrlBasedContent<FileInfo>>; - } // namespace EventContent -} // namespace QMatrixClient + } // namespace EventContent +} // namespace QMatrixClient diff --git a/lib/events/roomtombstoneevent.cpp b/lib/events/roomtombstoneevent.cpp index 9c3bafd4..a74bb367 100644 --- a/lib/events/roomtombstoneevent.cpp +++ b/lib/events/roomtombstoneevent.cpp @@ -1,20 +1,20 @@ /****************************************************************************** -* Copyright (C) 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 -*/ + * Copyright (C) 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 + */ #include "roomtombstoneevent.h" diff --git a/lib/events/roomtombstoneevent.h b/lib/events/roomtombstoneevent.h index c7008ec4..5b7ade76 100644 --- a/lib/events/roomtombstoneevent.h +++ b/lib/events/roomtombstoneevent.h @@ -1,41 +1,41 @@ /****************************************************************************** -* Copyright (C) 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 -*/ + * Copyright (C) 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 + */ #pragma once #include "stateevent.h" -namespace QMatrixClient -{ +namespace QMatrixClient { class RoomTombstoneEvent : public StateEventBase { public: - DEFINE_EVENT_TYPEID("m.room.tombstone", RoomTombstoneEvent) + DEFINE_EVENT_TYPEID("m.room.tombstone", RoomTombstoneEvent) - explicit RoomTombstoneEvent() - : StateEventBase(typeId(), matrixTypeId()) - { } - explicit RoomTombstoneEvent(const QJsonObject& obj) - : StateEventBase(typeId(), obj) - { } + explicit RoomTombstoneEvent() : StateEventBase(typeId(), matrixTypeId()) + { + } + explicit RoomTombstoneEvent(const QJsonObject& obj) + : StateEventBase(typeId(), obj) + { + } - QString serverMessage() const; - QString successorRoomId() const; + QString serverMessage() const; + QString successorRoomId() const; }; REGISTER_EVENT_TYPE(RoomTombstoneEvent) } diff --git a/lib/events/simplestateevents.h b/lib/events/simplestateevents.h index 2c23d9ca..430eacb0 100644 --- a/lib/events/simplestateevents.h +++ b/lib/events/simplestateevents.h @@ -13,7 +13,7 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #pragma once @@ -22,71 +22,70 @@ #include "converters.h" -namespace QMatrixClient -{ - namespace EventContent - { - template <typename T> - class SimpleContent +namespace QMatrixClient { + namespace EventContent { + template <typename T> class SimpleContent { public: - using value_type = T; + using value_type = T; - // The constructor is templated to enable perfect forwarding - template <typename TT> - SimpleContent(QString keyName, TT&& value) - : value(std::forward<TT>(value)), key(std::move(keyName)) - { } - SimpleContent(const QJsonObject& json, QString keyName) - : value(fromJson<T>(json[keyName])) - , key(std::move(keyName)) - { } - QJsonObject toJson() const - { - return { { key, QMatrixClient::toJson(value) } }; - } + // The constructor is templated to enable perfect forwarding + template <typename TT> + SimpleContent(QString keyName, TT&& value) + : value(std::forward<TT>(value)), key(std::move(keyName)) + { + } + SimpleContent(const QJsonObject& json, QString keyName) + : value(fromJson<T>(json[keyName])), key(std::move(keyName)) + { + } + QJsonObject toJson() const + { + return { { key, QMatrixClient::toJson(value) } }; + } public: - T value; + T value; protected: - QString key; + QString key; }; } // namespace EventContent -#define DEFINE_SIMPLE_STATE_EVENT(_Name, _TypeId, _ValueType, _ContentKey) \ - class _Name : public StateEvent<EventContent::SimpleContent<_ValueType>> \ - { \ - public: \ - using value_type = content_type::value_type; \ - DEFINE_EVENT_TYPEID(_TypeId, _Name) \ - explicit _Name() : _Name(value_type()) { } \ - template <typename T> \ - explicit _Name(T&& value) \ - : StateEvent(typeId(), matrixTypeId(), \ - QStringLiteral(#_ContentKey), \ - std::forward<T>(value)) \ - { } \ - explicit _Name(QJsonObject obj) \ - : StateEvent(typeId(), std::move(obj), \ - QStringLiteral(#_ContentKey)) \ - { } \ - auto _ContentKey() const { return content().value; } \ - }; \ - REGISTER_EVENT_TYPE(_Name) \ +#define DEFINE_SIMPLE_STATE_EVENT(_Name, _TypeId, _ValueType, _ContentKey) \ + class _Name : public StateEvent<EventContent::SimpleContent<_ValueType>> \ + { \ + public: \ + using value_type = content_type::value_type; \ + DEFINE_EVENT_TYPEID(_TypeId, _Name) \ + explicit _Name() : _Name(value_type()) {} \ + template <typename T> \ + explicit _Name(T&& value) \ + : StateEvent(typeId(), matrixTypeId(), \ + QStringLiteral(#_ContentKey), std::forward<T>(value)) \ + { \ + } \ + explicit _Name(QJsonObject obj) \ + : StateEvent(typeId(), std::move(obj), \ + QStringLiteral(#_ContentKey)) \ + { \ + } \ + auto _ContentKey() const { return content().value; } \ + }; \ + REGISTER_EVENT_TYPE(_Name) \ // End of macro DEFINE_SIMPLE_STATE_EVENT(RoomNameEvent, "m.room.name", QString, name) DEFINE_EVENTTYPE_ALIAS(RoomName, RoomNameEvent) - DEFINE_SIMPLE_STATE_EVENT(RoomAliasesEvent, "m.room.aliases", - QStringList, aliases) + DEFINE_SIMPLE_STATE_EVENT(RoomAliasesEvent, "m.room.aliases", QStringList, + aliases) DEFINE_EVENTTYPE_ALIAS(RoomAliases, RoomAliasesEvent) DEFINE_SIMPLE_STATE_EVENT(RoomCanonicalAliasEvent, "m.room.canonical_alias", QString, alias) DEFINE_EVENTTYPE_ALIAS(RoomCanonicalAlias, RoomCanonicalAliasEvent) DEFINE_SIMPLE_STATE_EVENT(RoomTopicEvent, "m.room.topic", QString, topic) DEFINE_EVENTTYPE_ALIAS(RoomTopic, RoomTopicEvent) - DEFINE_SIMPLE_STATE_EVENT(EncryptionEvent, "m.room.encryption", - QString, algorithm) + DEFINE_SIMPLE_STATE_EVENT(EncryptionEvent, "m.room.encryption", QString, + algorithm) DEFINE_EVENTTYPE_ALIAS(RoomEncryption, EncryptionEvent) } // namespace QMatrixClient diff --git a/lib/events/stateevent.cpp b/lib/events/stateevent.cpp index e96614d2..f172edb6 100644 --- a/lib/events/stateevent.cpp +++ b/lib/events/stateevent.cpp @@ -1,20 +1,20 @@ /****************************************************************************** -* Copyright (C) 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 -*/ + * Copyright (C) 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 + */ #include "stateevent.h" @@ -24,9 +24,9 @@ using namespace QMatrixClient; // StateEventBase itself can be instantiated if there's a state_key JSON key // but the event type is unknown. [[gnu::unused]] static auto stateEventTypeInitialised = - RoomEvent::factory_t::addMethod( - [] (const QJsonObject& json, const QString& matrixType) -> StateEventPtr - { + RoomEvent::factory_t::addMethod([](const QJsonObject& json, + const QString& matrixType) + -> StateEventPtr { if (!json.contains("state_key")) return nullptr; @@ -53,6 +53,7 @@ void StateEventBase::dumpTo(QDebug dbg) const dbg << '<' << stateKey() << "> "; if (unsignedJson().contains(PrevContentKeyL)) dbg << QJsonDocument(unsignedJson()[PrevContentKeyL].toObject()) - .toJson(QJsonDocument::Compact) << " -> "; + .toJson(QJsonDocument::Compact) + << " -> "; RoomEvent::dumpTo(dbg); } diff --git a/lib/events/stateevent.h b/lib/events/stateevent.h index 3f54f7bf..1a02646b 100644 --- a/lib/events/stateevent.h +++ b/lib/events/stateevent.h @@ -1,119 +1,127 @@ /****************************************************************************** -* Copyright (C) 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 -*/ + * Copyright (C) 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 + */ #pragma once #include "roomevent.h" namespace QMatrixClient { - class StateEventBase: public RoomEvent + class StateEventBase : public RoomEvent { public: - using factory_t = EventFactory<StateEventBase>; + using factory_t = EventFactory<StateEventBase>; - using RoomEvent::RoomEvent; - ~StateEventBase() override = default; + using RoomEvent::RoomEvent; + ~StateEventBase() override = default; - bool isStateEvent() const override { return true; } - QString replacedState() const; - void dumpTo(QDebug dbg) const override; + bool isStateEvent() const override { return true; } + QString replacedState() const; + void dumpTo(QDebug dbg) const override; - virtual bool repeatsState() const; + virtual bool repeatsState() const; }; using StateEventPtr = event_ptr_tt<StateEventBase>; using StateEvents = EventsArray<StateEventBase>; - template <> - inline bool is<StateEventBase>(const Event& e) { return e.isStateEvent(); } + template <> inline bool is<StateEventBase>(const Event& e) + { + return e.isStateEvent(); + } /** * A combination of event type and state key uniquely identifies a piece * of state in Matrix. - * \sa https://matrix.org/docs/spec/client_server/unstable.html#types-of-room-events + * \sa + * https://matrix.org/docs/spec/client_server/unstable.html#types-of-room-events */ using StateEventKey = QPair<QString, QString>; - template <typename ContentT> - struct Prev - { + template <typename ContentT> struct Prev { template <typename... ContentParamTs> explicit Prev(const QJsonObject& unsignedJson, ContentParamTs&&... contentParams) - : senderId(unsignedJson.value("prev_sender"_ls).toString()) - , content(unsignedJson.value(PrevContentKeyL).toObject(), - std::forward<ContentParamTs>(contentParams)...) - { } + : senderId(unsignedJson.value("prev_sender"_ls).toString()), + content(unsignedJson.value(PrevContentKeyL).toObject(), + std::forward<ContentParamTs>(contentParams)...) + { + } QString senderId; ContentT content; }; - template <typename ContentT> - class StateEvent: public StateEventBase + template <typename ContentT> class StateEvent : public StateEventBase { public: - using content_type = ContentT; + using content_type = ContentT; - template <typename... ContentParamTs> - explicit StateEvent(Type type, const QJsonObject& fullJson, - ContentParamTs&&... contentParams) - : StateEventBase(type, fullJson) - , _content(contentJson(), - std::forward<ContentParamTs>(contentParams)...) - { - const auto& unsignedData = unsignedJson(); - if (unsignedData.contains(PrevContentKeyL)) - _prev = std::make_unique<Prev<ContentT>>(unsignedData, - std::forward<ContentParamTs>(contentParams)...); - } - template <typename... ContentParamTs> - explicit StateEvent(Type type, event_mtype_t matrixType, - ContentParamTs&&... contentParams) - : StateEventBase(type, matrixType) - , _content(std::forward<ContentParamTs>(contentParams)...) - { - editJson().insert(ContentKey, _content.toJson()); - } + template <typename... ContentParamTs> + explicit StateEvent(Type type, const QJsonObject& fullJson, + ContentParamTs&&... contentParams) + : StateEventBase(type, fullJson), + _content(contentJson(), + std::forward<ContentParamTs>(contentParams)...) + { + const auto& unsignedData = unsignedJson(); + if (unsignedData.contains(PrevContentKeyL)) + _prev = std::make_unique<Prev<ContentT>>( + unsignedData, + std::forward<ContentParamTs>(contentParams)...); + } + template <typename... ContentParamTs> + explicit StateEvent(Type type, event_mtype_t matrixType, + ContentParamTs&&... contentParams) + : StateEventBase(type, matrixType), + _content(std::forward<ContentParamTs>(contentParams)...) + { + editJson().insert(ContentKey, _content.toJson()); + } - const ContentT& content() const { return _content; } - template <typename VisitorT> - void editContent(VisitorT&& visitor) - { - visitor(_content); - editJson()[ContentKeyL] = _content.toJson(); - } - [[deprecated("Use prevContent instead")]] - const ContentT* prev_content() const { return prevContent(); } - const ContentT* prevContent() const - { return _prev ? &_prev->content : nullptr; } - QString prevSenderId() const - { return _prev ? _prev->senderId : QString(); } + const ContentT& content() const { return _content; } + template <typename VisitorT> void editContent(VisitorT&& visitor) + { + visitor(_content); + editJson()[ContentKeyL] = _content.toJson(); + } + [[deprecated("Use prevContent instead")]] const ContentT* + prev_content() const + { + return prevContent(); + } + const ContentT* prevContent() const + { + return _prev ? &_prev->content : nullptr; + } + QString prevSenderId() const + { + return _prev ? _prev->senderId : QString(); + } private: - ContentT _content; - std::unique_ptr<Prev<ContentT>> _prev; + ContentT _content; + std::unique_ptr<Prev<ContentT>> _prev; }; } // namespace QMatrixClient namespace std { - template <> struct hash<QMatrixClient::StateEventKey> - { - size_t operator()(const QMatrixClient::StateEventKey& k) const Q_DECL_NOEXCEPT + template <> struct hash<QMatrixClient::StateEventKey> { + size_t + operator()(const QMatrixClient::StateEventKey& k) const Q_DECL_NOEXCEPT { return qHash(k); } diff --git a/lib/events/typingevent.cpp b/lib/events/typingevent.cpp index 0d39d1be..ee3d6b67 100644 --- a/lib/events/typingevent.cpp +++ b/lib/events/typingevent.cpp @@ -13,7 +13,7 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "typingevent.h" @@ -22,11 +22,9 @@ using namespace QMatrixClient; -TypingEvent::TypingEvent(const QJsonObject& obj) - : Event(typeId(), obj) +TypingEvent::TypingEvent(const QJsonObject& obj) : Event(typeId(), obj) { const auto& array = contentJson()["user_ids"_ls].toArray(); - for(const auto& user: array ) + for (const auto& user : array) _users.push_back(user.toString()); } - diff --git a/lib/events/typingevent.h b/lib/events/typingevent.h index 27b668b4..f66a1fbc 100644 --- a/lib/events/typingevent.h +++ b/lib/events/typingevent.h @@ -13,27 +13,26 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #pragma once #include "event.h" -namespace QMatrixClient -{ - class TypingEvent: public Event +namespace QMatrixClient { + class TypingEvent : public Event { public: - DEFINE_EVENT_TYPEID("m.typing", TypingEvent) + DEFINE_EVENT_TYPEID("m.typing", TypingEvent) - TypingEvent(const QJsonObject& obj); + TypingEvent(const QJsonObject& obj); - const QStringList& users() const { return _users; } + const QStringList& users() const { return _users; } private: - QStringList _users; + QStringList _users; }; REGISTER_EVENT_TYPE(TypingEvent) DEFINE_EVENTTYPE_ALIAS(Typing, TypingEvent) -} // namespace QMatrixClient +} // namespace QMatrixClient |