diff options
author | Kitsune Ral <Kitsune-Ral@users.sf.net> | 2017-11-28 12:42:03 +0900 |
---|---|---|
committer | Kitsune Ral <Kitsune-Ral@users.sf.net> | 2017-11-28 12:42:03 +0900 |
commit | 357625eb55e2f4569bb487ffe14a9236188e25f3 (patch) | |
tree | d39340ab74f25a23a5855f679973628f7457fd87 /events | |
parent | 94e6636d8225a0561ed7df3fa8081c5b0183610c (diff) | |
parent | 8f762a2458db773f6db24b568b2e944427297c2b (diff) | |
download | libquotient-357625eb55e2f4569bb487ffe14a9236188e25f3.tar.gz libquotient-357625eb55e2f4569bb487ffe14a9236188e25f3.zip |
Merge branch 'master' into kitsune-gtad
Diffstat (limited to 'events')
-rw-r--r-- | events/encryptedevent.cpp | 5 | ||||
-rw-r--r-- | events/event.cpp | 61 | ||||
-rw-r--r-- | events/event.h | 103 | ||||
-rw-r--r-- | events/eventcontent.cpp | 63 | ||||
-rw-r--r-- | events/eventcontent.h | 295 | ||||
-rw-r--r-- | events/receiptevent.cpp | 6 | ||||
-rw-r--r-- | events/receiptevent.h | 2 | ||||
-rw-r--r-- | events/roomaliasesevent.cpp | 43 | ||||
-rw-r--r-- | events/roomaliasesevent.h | 37 | ||||
-rw-r--r-- | events/roomavatarevent.cpp (renamed from events/roomtopicevent.cpp) | 5 | ||||
-rw-r--r-- | events/roomavatarevent.h (renamed from events/encryptedevent.h) | 22 | ||||
-rw-r--r-- | events/roomcanonicalaliasevent.cpp | 21 | ||||
-rw-r--r-- | events/roomcanonicalaliasevent.h | 38 | ||||
-rw-r--r-- | events/roommemberevent.cpp | 48 | ||||
-rw-r--r-- | events/roommemberevent.h | 43 | ||||
-rw-r--r-- | events/roommessageevent.cpp | 63 | ||||
-rw-r--r-- | events/roommessageevent.h | 246 | ||||
-rw-r--r-- | events/roomnameevent.cpp | 22 | ||||
-rw-r--r-- | events/roomnameevent.h | 38 | ||||
-rw-r--r-- | events/roomtopicevent.h | 50 | ||||
-rw-r--r-- | events/simplestateevents.h | 54 | ||||
-rw-r--r-- | events/typingevent.h | 2 | ||||
-rw-r--r-- | events/unknownevent.cpp | 64 | ||||
-rw-r--r-- | events/unknownevent.h | 40 |
24 files changed, 625 insertions, 746 deletions
diff --git a/events/encryptedevent.cpp b/events/encryptedevent.cpp deleted file mode 100644 index 90e77c36..00000000 --- a/events/encryptedevent.cpp +++ /dev/null @@ -1,5 +0,0 @@ -// -// Created by rusakov on 26/09/2017. -// - -#include "encryptedevent.h" diff --git a/events/event.cpp b/events/event.cpp index 304f2af6..44b742c1 100644 --- a/events/event.cpp +++ b/events/event.cpp @@ -19,14 +19,11 @@ #include "event.h" #include "roommessageevent.h" -#include "roomnameevent.h" -#include "roomaliasesevent.h" -#include "roomcanonicalaliasevent.h" +#include "simplestateevents.h" #include "roommemberevent.h" -#include "roomtopicevent.h" +#include "roomavatarevent.h" #include "typingevent.h" #include "receiptevent.h" -#include "encryptedevent.h" #include "logging.h" #include <QtCore/QJsonDocument> @@ -53,32 +50,24 @@ QJsonObject Event::originalJsonObject() const return _originalJson; } -QDateTime Event::toTimestamp(const QJsonValue& v) +const QJsonObject Event::contentJson() const { - Q_ASSERT(v.isDouble() || v.isNull() || v.isUndefined()); - return QDateTime::fromMSecsSinceEpoch( - static_cast<long long int>(v.toDouble()), Qt::UTC); + return _originalJson["content"].toObject(); } -QStringList Event::toStringList(const QJsonValue& v) +template <typename BaseEventT> +inline BaseEventT* makeIfMatches(const QJsonObject&, const QString&) { - Q_ASSERT(v.isArray() || v.isNull() || v.isUndefined()); - - QStringList l; - for( const QJsonValue& e : v.toArray() ) - l.push_back(e.toString()); - return l; + return nullptr; } -const QJsonObject Event::contentJson() const +template <typename BaseEventT, typename EventT, typename... EventTs> +inline BaseEventT* makeIfMatches(const QJsonObject& o, const QString& selector) { - return _originalJson["content"].toObject(); -} + if (selector == EventT::TypeId) + return new EventT(o); -template <typename EventT> -EventT* make(const QJsonObject& o) -{ - return new EventT(o); + return makeIfMatches<BaseEventT, EventTs...>(o, selector); } Event* Event::fromJson(const QJsonObject& obj) @@ -87,17 +76,14 @@ Event* Event::fromJson(const QJsonObject& obj) if (auto e = RoomEvent::fromJson(obj)) return e; - return dispatch<Event*>(obj).to(obj["type"].toString(), - "m.typing", make<TypingEvent>, - "m.receipt", make<ReceiptEvent>, - /* Insert new event types (except room events) BEFORE this line */ - nullptr - ); + return makeIfMatches<Event, + TypingEvent, ReceiptEvent>(obj, obj["type"].toString()); } RoomEvent::RoomEvent(Type type, const QJsonObject& rep) : Event(type, rep), _id(rep["event_id"].toString()) - , _serverTimestamp(toTimestamp(rep["origin_server_ts"])) + , _serverTimestamp( + QMatrixClient::fromJson<QDateTime>(rep["origin_server_ts"])) , _roomId(rep["room_id"].toString()) , _senderId(rep["sender"].toString()) , _txnId(rep["unsigned"].toObject().value("transactionId").toString()) @@ -129,15 +115,8 @@ void RoomEvent::addId(const QString& id) RoomEvent* RoomEvent::fromJson(const QJsonObject& obj) { - return dispatch<RoomEvent*>(obj).to(obj["type"].toString(), - "m.room.message", make<RoomMessageEvent>, - "m.room.name", make<RoomNameEvent>, - "m.room.aliases", make<RoomAliasesEvent>, - "m.room.canonical_alias", make<RoomCanonicalAliasEvent>, - "m.room.member", make<RoomMemberEvent>, - "m.room.topic", make<RoomTopicEvent>, - "m.room.encryption", make<EncryptionEvent>, - /* Insert new ROOM event types BEFORE this line */ - nullptr - ); + return makeIfMatches<RoomEvent, + RoomMessageEvent, RoomNameEvent, RoomAliasesEvent, + RoomCanonicalAliasEvent, RoomMemberEvent, RoomTopicEvent, + RoomAvatarEvent, EncryptionEvent>(obj, obj["type"].toString()); } diff --git a/events/event.h b/events/event.h index ec993522..cc99b57b 100644 --- a/events/event.h +++ b/events/event.h @@ -31,11 +31,18 @@ namespace QMatrixClient { Q_GADGET public: - enum class Type + enum class Type : quint16 { - RoomMessage, RoomName, RoomAliases, RoomCanonicalAlias, - RoomMember, RoomTopic, RoomEncryption, RoomEncryptedMessage, - Typing, Receipt, Unknown + Unknown = 0, + Typing, Receipt, + RoomEventBase = 0x1000, + RoomMessage = RoomEventBase + 1, + RoomEncryptedMessage, + RoomStateEventBase = 0x1800, + RoomName = RoomStateEventBase + 1, + RoomAliases, RoomCanonicalAlias, RoomMember, RoomTopic, + RoomAvatar, RoomEncryption, + Reserved = 0x2000 }; explicit Event(Type type) : _type(type) { } @@ -43,6 +50,10 @@ namespace QMatrixClient Event(const Event&) = delete; Type type() const { return _type; } + bool isStateEvent() const + { + return (quint16(_type) & 0x1800) == 0x1800; + } QByteArray originalJson() const; QJsonObject originalJsonObject() const; @@ -52,12 +63,13 @@ namespace QMatrixClient // (and in most cases it will be a combination of other fields // instead of "content" field). + /** Create an event with proper type from a JSON object + * Use this factory to detect the type from the JSON object contents + * and create an event object of that type. + */ static Event* fromJson(const QJsonObject& obj); protected: - static QDateTime toTimestamp(const QJsonValue& v); - static QStringList toStringList(const QJsonValue& v); - const QJsonObject contentJson() const; private: @@ -69,31 +81,27 @@ namespace QMatrixClient Q_PROPERTY(QJsonObject contentJson READ contentJson CONSTANT) }; using EventType = Event::Type; - template <typename EventT> - using EventsBatch = std::vector<EventT*>; - using Events = EventsBatch<Event>; - template <typename BaseEventT> - BaseEventT* makeEvent(const QJsonObject& obj) - { - if (auto e = BaseEventT::fromJson(obj)) - return e; - - return new BaseEventT(EventType::Unknown, obj); - } - - template <typename BaseEventT = Event, - typename BatchT = EventsBatch<BaseEventT> > - BatchT makeEvents(const QJsonArray& objs) + template <typename EventT> + class EventsBatch : public std::vector<EventT*> { - BatchT evs; - // The below line accommodates the difference in size types of - // STL and Qt containers. - evs.reserve(static_cast<typename BatchT::size_type>(objs.size())); - for (auto obj: objs) - evs.push_back(makeEvent<BaseEventT>(obj.toObject())); - return evs; - } + public: + void fromJson(const QJsonObject& container, const QString& node) + { + const auto objs = container.value(node).toArray(); + using size_type = typename std::vector<EventT*>::size_type; + // The below line accommodates the difference in size types of + // STL and Qt containers. + this->reserve(static_cast<size_type>(objs.size())); + for (auto objValue: objs) + { + const auto o = objValue.toObject(); + auto e = EventT::fromJson(o); + this->push_back(e ? e : new EventT(EventType::Unknown, o)); + } + } + }; + using Events = EventsBatch<Event>; /** This class corresponds to m.room.* events */ class RoomEvent : public Event @@ -146,6 +154,41 @@ namespace QMatrixClient QString _txnId; }; using RoomEvents = EventsBatch<RoomEvent>; + + template <typename ContentT> + class StateEvent: public RoomEvent + { + public: + using content_type = ContentT; + + template <typename... ContentParamTs> + explicit StateEvent(Type type, const QJsonObject& obj, + ContentParamTs&&... contentParams) + : RoomEvent(obj.contains("state_key") ? type : Type::Unknown, + obj) + , _content(contentJson(), + std::forward<ContentParamTs>(contentParams)...) + { + if (obj.contains("prev_content")) + _prev.reset(new ContentT( + obj["prev_content"].toObject(), + std::forward<ContentParamTs>(contentParams)...)); + } + template <typename... ContentParamTs> + explicit StateEvent(Type type, ContentParamTs&&... contentParams) + : RoomEvent(type) + , _content(std::forward<ContentParamTs>(contentParams)...) + { } + + QJsonObject toJson() const { return _content.toJson(); } + + ContentT content() const { return _content; } + ContentT* prev_content() const { return _prev.data(); } + + protected: + ContentT _content; + QScopedPointer<ContentT> _prev; + }; } // namespace QMatrixClient Q_DECLARE_OPAQUE_POINTER(QMatrixClient::Event*) Q_DECLARE_METATYPE(QMatrixClient::Event*) diff --git a/events/eventcontent.cpp b/events/eventcontent.cpp new file mode 100644 index 00000000..dcbccf08 --- /dev/null +++ b/events/eventcontent.cpp @@ -0,0 +1,63 @@ +/****************************************************************************** + * Copyright (C) 2017 Kitsune Ral <kitsune-ral@users.sf.net> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "eventcontent.h" + +#include <QtCore/QUrl> +#include <QtCore/QMimeDatabase> + +using namespace QMatrixClient::EventContent; + +QJsonObject Base::toJson() const +{ + QJsonObject o; + fillJson(&o); + return o; +} + +QJsonObject InfoBase::toInfoJson() const +{ + QJsonObject info; + fillInfoJson(&info); + return info; +} + +void InfoBase::fillInfoJson(QJsonObject*) const { } + +FileInfo::FileInfo(const QUrl& u, int payloadSize, const QMimeType& mimeType, + const QString& originalFilename) + : InfoBase(mimeType), url(u), payloadSize(payloadSize) + , originalName(originalFilename) +{ } + +FileInfo::FileInfo(const QUrl& u, const QJsonObject& infoJson, + const QString& originalFilename) + : FileInfo(u, infoJson["size"].toInt(), + QMimeDatabase().mimeTypeForName(infoJson["mimetype"].toString()), + originalFilename) +{ + if (!mimeType.isValid()) + mimeType = QMimeDatabase().mimeTypeForData(QByteArray()); +} + +void FileInfo::fillInfoJson(QJsonObject* infoJson) const +{ + Q_ASSERT(infoJson); + infoJson->insert("size", payloadSize); + infoJson->insert("mimetype", mimeType.name()); +} diff --git a/events/eventcontent.h b/events/eventcontent.h new file mode 100644 index 00000000..60437995 --- /dev/null +++ b/events/eventcontent.h @@ -0,0 +1,295 @@ +/****************************************************************************** + * Copyright (C) 2017 Kitsune Ral <kitsune-ral@users.sf.net> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#pragma once + +// This file contains generic event content definitions, applicable to room +// message events as well as other events (e.g., avatars). + +#include "converters.h" + +#include <QtCore/QJsonObject> +#include <QtCore/QMimeType> +#include <QtCore/QUrl> +#include <QtCore/QSize> + +namespace QMatrixClient +{ + namespace EventContent + { + /** + * A base class for all content types that can be stored + * in a RoomMessageEvent + * + * Each content type class should have a constructor taking + * a QJsonObject and override fillJson() with an implementation + * that will fill the target QJsonObject with stored values. It is + * assumed but not required that a content object can also be created + * from plain data. fillJson() should only fill the main JSON object + * but not the "info" subobject if it exists for a certain content type; + * use \p InfoBase to de/serialize "info" parts with an optional URL + * on the top level. + */ + class Base + { + public: + virtual ~Base() = default; + + QJsonObject toJson() const; + + protected: + virtual void fillJson(QJsonObject* o) const = 0; + }; + + class TypedBase: public Base + { + public: + virtual QMimeType type() const = 0; + }; + + template <typename T = QString> + class SimpleContent: public Base + { + public: + 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(QMatrixClient::fromJson<T>(json[keyName])) + , key(std::move(keyName)) + { } + + T value; + + protected: + QString key; + + private: + void fillJson(QJsonObject* json) const override + { + Q_ASSERT(json); + json->insert(key, QMatrixClient::toJson(value)); + } + }; + + /** + * A base class for content types that have an "info" object in their + * JSON representation + * + * These include most multimedia types currently in the CS API spec. + * Derived classes should override fillInfoJson() to fill the "info" + * subobject, BUT NOT the main JSON object. Most but not all "info" + * classes (specifically, those deriving from FileInfo) should also + * have a constructor that accepts two parameters, QUrl and QJsonObject, + * in order to load the URL+info part from JSON. + */ + class InfoBase + { + public: + virtual ~InfoBase() = default; + + QJsonObject toInfoJson() const; + + QMimeType mimeType; + + protected: + InfoBase() = default; + explicit InfoBase(const QMimeType& type) : mimeType(type) { } + + virtual void fillInfoJson(QJsonObject* /*infoJson*/) const = 0; + }; + + // The below structures fairly follow CS spec 11.2.1.6. The overall + // set of attributes for each content types is a superset of the spec + // but specific aggregation structure is altered. See doc comments to + // each type for the list of available attributes. + + /** + * Base class for content types that consist of a URL along with + * additional information. Most of message types except textual fall + * under this category. + */ + class FileInfo: public InfoBase + { + public: + explicit FileInfo(const QUrl& u, int payloadSize = -1, + const QMimeType& mimeType = {}, + const QString& originalFilename = {}); + FileInfo(const QUrl& u, const QJsonObject& infoJson, + const QString& originalFilename = {}); + + QUrl url; + int payloadSize; + QString originalName; + + protected: + void fillInfoJson(QJsonObject* infoJson) const override; + }; + + /** + * A base class for image info types: image, thumbnail, video + * + * \tparam InfoT base info class; should derive from \p InfoBase + */ + template <class InfoT = FileInfo> + class ImageInfo : public InfoT + { + public: + explicit ImageInfo(const QUrl& u, int fileSize = -1, + QMimeType mimeType = {}, + const QSize& imageSize = {}) + : InfoT(u, fileSize, mimeType), imageSize(imageSize) + { } + ImageInfo(const QUrl& u, const QJsonObject& infoJson, + const QString& originalFilename = {}) + : InfoT(u, infoJson, originalFilename) + , imageSize(infoJson["w"].toInt(), infoJson["h"].toInt()) + { } + + QSize imageSize; + + protected: + void fillInfoJson(QJsonObject* infoJson) const override + { + InfoT::fillInfoJson(infoJson); + infoJson->insert("w", imageSize.width()); + infoJson->insert("h", imageSize.height()); + } + }; + + /** + * A base class for an info type that carries a thumbnail + * + * This class decorates the underlying type, adding ability to save/load + * a thumbnail to/from "info" subobject of the JSON representation of + * event content; namely, "info/thumbnail_url" and "info/thumbnail_info" + * fields are used. + * + * \tparam InfoT base info class; should derive from \p InfoBase + */ + template <class InfoT = InfoBase> + class Thumbnailed : public InfoT + { + public: + template <typename... ArgTs> + explicit Thumbnailed(const ImageInfo<>& thumbnail, + ArgTs&&... infoArgs) + : InfoT(std::forward<ArgTs>(infoArgs)...) + , thumbnail(thumbnail) + { } + + explicit Thumbnailed(const QJsonObject& infoJson) + : thumbnail(infoJson["thumbnail_url"].toString(), + infoJson["thumbnail_info"].toObject()) + { } + + Thumbnailed(const QUrl& u, const QJsonObject& infoJson, + const QString& originalFilename = {}) + : InfoT(u, infoJson, originalFilename) + , thumbnail(infoJson["thumbnail_url"].toString(), + infoJson["thumbnail_info"].toObject()) + { } + + ImageInfo<> thumbnail; + + protected: + void fillInfoJson(QJsonObject* infoJson) const override + { + InfoT::fillInfoJson(infoJson); + infoJson->insert("thumbnail_url", thumbnail.url.toString()); + infoJson->insert("thumbnail_info", thumbnail.toInfoJson()); + } + }; + + /** + * One more facility base class for content types that have a URL and + * additional info + * + * Types that derive from UrlWith<InfoT> take "url" and, optionally, + * "filename" values from the top-level JSON object and the rest of + * information from the "info" subobject. + * + * \tparam InfoT base info class; should derive from \p FileInfo or + * provide a constructor with a compatible signature + */ + template <class InfoT> // InfoT : public FileInfo + class UrlWith : public TypedBase, public InfoT + { + public: + using InfoT::InfoT; + explicit UrlWith(const QJsonObject& json) + : InfoT(json["url"].toString(), json["info"].toObject(), + json["filename"].toString()) + { } + + QMimeType type() const override { return InfoT::mimeType; } + + 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", InfoT::toInfoJson()); + } + }; + + /** + * Content class for m.image + * + * Available fields: + * - corresponding to the top-level JSON: + * - url + * - filename (extension to the spec) + * - corresponding to the "info" subobject: + * - payloadSize ("size" in JSON) + * - mimeType ("mimetype" in JSON) + * - imageSize (QSize for a combination of "h" and "w" in JSON) + * - thumbnail.url ("thumbnail_url" in JSON) + * - corresponding to the "info/thumbnail_info" subobject: contents of + * thumbnail field, in the same vein as for the main image: + * - payloadSize + * - mimeType + * - imageSize + */ + using ImageContent = UrlWith<Thumbnailed<ImageInfo<>>>; + + /** + * Content class for m.file + * + * Available fields: + * - corresponding to the top-level JSON: + * - url + * - filename + * - corresponding to the "info" subobject: + * - payloadSize ("size" in JSON) + * - mimeType ("mimetype" in JSON) + * - thumbnail.url ("thumbnail_url" in JSON) + * - corresponding to the "info/thumbnail_info" subobject: + * - thumbnail.payloadSize + * - thumbnail.mimeType + * - thumbnail.imageSize (QSize for "h" and "w" in JSON) + */ + using FileContent = UrlWith<Thumbnailed<FileInfo>>; + } // namespace EventContent +} // namespace QMatrixClient diff --git a/events/receiptevent.cpp b/events/receiptevent.cpp index 646bb989..b36ddb23 100644 --- a/events/receiptevent.cpp +++ b/events/receiptevent.cpp @@ -35,10 +35,9 @@ Example of a Receipt Event: #include "receiptevent.h" +#include "converters.h" #include "logging.h" -#include <QtCore/QJsonArray> - using namespace QMatrixClient; ReceiptEvent::ReceiptEvent(const QJsonObject& obj) @@ -62,7 +61,8 @@ ReceiptEvent::ReceiptEvent(const QJsonObject& obj) for( auto userIt = reads.begin(); userIt != reads.end(); ++userIt ) { const QJsonObject user = userIt.value().toObject(); - receipts.push_back({userIt.key(), toTimestamp(user["ts"])}); + receipts.push_back({userIt.key(), + QMatrixClient::fromJson<QDateTime>(user["ts"])}); } _eventsWithReceipts.push_back({eventIt.key(), receipts}); } diff --git a/events/receiptevent.h b/events/receiptevent.h index cbe36b10..15fdf946 100644 --- a/events/receiptevent.h +++ b/events/receiptevent.h @@ -43,6 +43,8 @@ namespace QMatrixClient { return _eventsWithReceipts; } bool unreadMessages() const { return _unreadMessages; } + static constexpr const char* const TypeId = "m.receipt"; + private: EventsWithReceipts _eventsWithReceipts; bool _unreadMessages; // Spec extension for caching purposes diff --git a/events/roomaliasesevent.cpp b/events/roomaliasesevent.cpp deleted file mode 100644 index 344b4367..00000000 --- a/events/roomaliasesevent.cpp +++ /dev/null @@ -1,43 +0,0 @@ -/****************************************************************************** - * Copyright (C) 2015 Felix Rohrbach <kde@fxrh.de> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -// Example of a RoomAliases Event: -// -// { -// "age":3758857346, -// "content":{ -// "aliases":["#freenode_#testest376:matrix.org"] -// }, -// "event_id":"$1439989428122drFjY:matrix.org", -// "origin_server_ts":1439989428910, -// "replaces_state":"$143613875199223YYPrN:matrix.org", -// "room_id":"!UoqtanuuSGTMvNRfDG:matrix.org", -// "state_key":"matrix.org", -// "type":"m.room.aliases", -// "user_id":"@appservice-irc:matrix.org" -// } - -#include "roomaliasesevent.h" - -using namespace QMatrixClient; - -RoomAliasesEvent::RoomAliasesEvent(const QJsonObject& obj) - : RoomEvent(Type::RoomAliases, obj) - , _aliases(toStringList(contentJson()["aliases"])) -{ } - diff --git a/events/roomaliasesevent.h b/events/roomaliasesevent.h deleted file mode 100644 index efafcb30..00000000 --- a/events/roomaliasesevent.h +++ /dev/null @@ -1,37 +0,0 @@ -/****************************************************************************** - * Copyright (C) 2015 Felix Rohrbach <kde@fxrh.de> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#pragma once - -#include "event.h" - -#include <QtCore/QStringList> - -namespace QMatrixClient -{ - class RoomAliasesEvent: public RoomEvent - { - public: - explicit RoomAliasesEvent(const QJsonObject& obj); - - QStringList aliases() const { return _aliases; } - - private: - QStringList _aliases; - }; -} // namespace QMatrixClient diff --git a/events/roomtopicevent.cpp b/events/roomavatarevent.cpp index 26677e78..7a5f82a1 100644 --- a/events/roomtopicevent.cpp +++ b/events/roomavatarevent.cpp @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (C) 2015 Felix Rohrbach <kde@fxrh.de> + * Copyright (C) 2017 Kitsune Ral <kitsune-ral@users.sf.net> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -16,7 +16,8 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "roomtopicevent.h" +#include "roomavatarevent.h" using namespace QMatrixClient; + diff --git a/events/encryptedevent.h b/events/roomavatarevent.h index 9db462e1..ccfe8fbf 100644 --- a/events/encryptedevent.h +++ b/events/roomavatarevent.h @@ -20,20 +20,24 @@ #include "event.h" +#include <utility> + +#include "eventcontent.h" + namespace QMatrixClient { - class EncryptionEvent : public RoomEvent + 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. public: - explicit EncryptionEvent(const QJsonObject& obj) - : RoomEvent(Type::RoomEncryption, obj) - , _algorithm(contentJson()["algorithm"].toString()) + explicit RoomAvatarEvent(const QJsonObject& obj) + : StateEvent(Type::RoomAvatar, obj) { } - QString algorithm() const { return _algorithm; } - - private: - QString _algorithm; + static constexpr const char* TypeId = "m.room.avatar"; }; -} // namespace QMatrixClient +} // namespace QMatrixClient diff --git a/events/roomcanonicalaliasevent.cpp b/events/roomcanonicalaliasevent.cpp deleted file mode 100644 index 6884bc15..00000000 --- a/events/roomcanonicalaliasevent.cpp +++ /dev/null @@ -1,21 +0,0 @@ -/****************************************************************************** - * Copyright (C) 2016 Felix Rohrbach <kde@fxrh.de> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "roomcanonicalaliasevent.h" - -using namespace QMatrixClient; diff --git a/events/roomcanonicalaliasevent.h b/events/roomcanonicalaliasevent.h deleted file mode 100644 index 72620d74..00000000 --- a/events/roomcanonicalaliasevent.h +++ /dev/null @@ -1,38 +0,0 @@ -/****************************************************************************** - * Copyright (C) 2016 Felix Rohrbach <kde@fxrh.de> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#pragma once - -#include "event.h" - -namespace QMatrixClient -{ - class RoomCanonicalAliasEvent : public RoomEvent - { - public: - explicit RoomCanonicalAliasEvent(const QJsonObject& obj) - : RoomEvent(Type::RoomCanonicalAlias, obj) - , _canonicalAlias(contentJson()["alias"].toString()) - { } - - QString alias() const { return _canonicalAlias; } - - private: - QString _canonicalAlias; - }; -} // namespace QMatrixClient diff --git a/events/roommemberevent.cpp b/events/roommemberevent.cpp index 19f116d2..76df5f2e 100644 --- a/events/roommemberevent.cpp +++ b/events/roommemberevent.cpp @@ -20,23 +20,45 @@ #include "logging.h" +#include <array> + using namespace QMatrixClient; -static const auto membershipStrings = - { "invite", "join", "knock", "leave", "ban" }; +static const std::array<QString, 5> membershipStrings = { { + QStringLiteral("invite"), QStringLiteral("join"), + QStringLiteral("knock"), QStringLiteral("leave"), + QStringLiteral("ban") +} }; -RoomMemberEvent::RoomMemberEvent(const QJsonObject& obj) - : RoomEvent(Type::RoomMember, obj), _userId(obj["state_key"].toString()) +namespace QMatrixClient { - const auto contentObj = contentJson(); - _displayName = contentObj["displayname"].toString(); - _avatarUrl = contentObj["avatar_url"].toString(); - QString membershipString = contentObj["membership"].toString(); - for (auto it = membershipStrings.begin(); it != membershipStrings.end(); ++it) - if (membershipString == *it) + template <> + struct FromJson<MembershipType> + { + MembershipType operator()(const QJsonValue& jv) const { - _membership = MembershipType(it - membershipStrings.begin()); - return; + const auto& membershipString = jv.toString(); + for (auto it = membershipStrings.begin(); + it != membershipStrings.end(); ++it) + if (membershipString == *it) + return MembershipType(it - membershipStrings.begin()); + + qCWarning(EVENTS) << "Unknown MembershipType: " << membershipString; + return MembershipType::Join; } - qCWarning(EVENTS) << "Unknown MembershipType: " << membershipString; + }; +} + +MemberEventContent::MemberEventContent(const QJsonObject& json) + : membership(fromJson<MembershipType>(json["membership"])) + , displayName(json["displayname"].toString()) + , avatarUrl(json["avatar_url"].toString()) +{ } + +void MemberEventContent::fillJson(QJsonObject* o) const +{ + Q_ASSERT(o); + o->insert("membership", membershipStrings[membership]); + o->insert("displayname", displayName); + o->insert("avatar_url", avatarUrl.toString()); } diff --git a/events/roommemberevent.h b/events/roommemberevent.h index 9ebb75ee..d0c63f15 100644 --- a/events/roommemberevent.h +++ b/events/roommemberevent.h @@ -20,30 +20,49 @@ #include "event.h" +#include "eventcontent.h" + #include <QtCore/QUrl> namespace QMatrixClient { - class RoomMemberEvent: public RoomEvent + class MemberEventContent: public EventContent::Base + { + public: + enum MembershipType : size_t {Invite = 0, Join, Knock, Leave, Ban}; + + MemberEventContent(const QJsonObject& json); + + MembershipType membership; + QString displayName; + QUrl avatarUrl; + + protected: + void fillJson(QJsonObject* o) const override; + }; + + using MembershipType = MemberEventContent::MembershipType; + + class RoomMemberEvent: public StateEvent<MemberEventContent> { Q_GADGET public: - enum MembershipType : int {Invite = 0, Join, Knock, Leave, Ban}; + static constexpr const char* TypeId = "m.room.member"; - explicit RoomMemberEvent(const QJsonObject& obj); + using MembershipType = MemberEventContent::MembershipType; - MembershipType membership() const { return _membership; } - const QString& userId() const { return _userId; } - const QString& displayName() const { return _displayName; } - const QUrl& avatarUrl() const { return _avatarUrl; } + explicit RoomMemberEvent(const QJsonObject& obj) + : StateEvent(Type::RoomMember, obj) + , _userId(obj["state_key"].toString()) + { } + + MembershipType membership() const { return content().membership; } + QString userId() const { return _userId; } + QString displayName() const { return content().displayName; } + QUrl avatarUrl() const { return content().avatarUrl; } private: - MembershipType _membership; QString _userId; - QString _displayName; - QUrl _avatarUrl; - REGISTER_ENUM(MembershipType) }; - using MembershipType = RoomMemberEvent::MembershipType; } // namespace QMatrixClient diff --git a/events/roommessageevent.cpp b/events/roommessageevent.cpp index 3fb0226a..f06474e9 100644 --- a/events/roommessageevent.cpp +++ b/events/roommessageevent.cpp @@ -23,12 +23,12 @@ #include <QtCore/QMimeDatabase> using namespace QMatrixClient; -using namespace MessageEventContent; +using namespace EventContent; using MsgType = RoomMessageEvent::MsgType; template <typename ContentT> -Base* make(const QJsonObject& json) +TypedBase* make(const QJsonObject& json) { return new ContentT(json); } @@ -37,7 +37,7 @@ struct MsgTypeDesc { QString jsonType; MsgType enumType; - Base* (*maker)(const QJsonObject&); + TypedBase* (*maker)(const QJsonObject&); }; const std::vector<MsgTypeDesc> msgTypes = @@ -74,7 +74,7 @@ MsgType jsonToMsgType(const QString& jsonType) } RoomMessageEvent::RoomMessageEvent(const QString& plainBody, - MsgType msgType, Base* content) + MsgType msgType, TypedBase* content) : RoomMessageEvent(plainBody, msgTypeToJson(msgType), content) { } @@ -112,7 +112,7 @@ RoomMessageEvent::MsgType RoomMessageEvent::msgtype() const QMimeType RoomMessageEvent::mimeType() const { - return _content ? _content->mimeType : + return _content ? _content->type() : QMimeDatabase().mimeTypeForName("text/plain"); } @@ -124,22 +124,8 @@ QJsonObject RoomMessageEvent::toJson() const return obj; } -QJsonObject Base::toJson() const -{ - QJsonObject o; - fillJson(&o); - return o; -} - -QJsonObject InfoBase::toInfoJson() const -{ - QJsonObject info; - fillInfoJson(&info); - return info; -} - TextContent::TextContent(const QString& text, const QString& contentType) - : Base(QMimeDatabase().mimeTypeForName(contentType)), body(text) + : mimeType(QMimeDatabase().mimeTypeForName(contentType)), body(text) { } TextContent::TextContent(const QJsonObject& json) @@ -167,38 +153,6 @@ void TextContent::fillJson(QJsonObject* json) const json->insert("formatted_body", body); } -FileInfo::FileInfo(const QUrl& u, int payloadSize, const QMimeType& mimeType, - const QString& originalFilename) - : InfoBase(mimeType), url(u), payloadSize(payloadSize) - , originalName(originalFilename) -{ } - -FileInfo::FileInfo(const QUrl& u, const QJsonObject& infoJson, - const QString& originalFilename) - : FileInfo(u, infoJson["size"].toInt(), - QMimeDatabase().mimeTypeForName(infoJson["mimetype"].toString()), - originalFilename) -{ - if (!mimeType.isValid()) - mimeType = QMimeDatabase().mimeTypeForData(QByteArray()); -} - -void FileInfo::fillInfoJson(QJsonObject* infoJson) const -{ - Q_ASSERT(infoJson); - infoJson->insert("size", payloadSize); - infoJson->insert("mimetype", mimeType.name()); -} - -void FileInfo::fillJson(QJsonObject* json) const -{ - Q_ASSERT(json); - json->insert("url", url.toString()); - if (!originalName.isEmpty()) - json->insert("filename", originalName); - json->insert("info", toInfoJson()); -} - LocationContent::LocationContent(const QString& geoUri, const ImageInfo<>& thumbnail) : Thumbnailed<>(thumbnail), geoUri(geoUri) @@ -216,6 +170,11 @@ void LocationContent::fillJson(QJsonObject* o) const o->insert("info", Thumbnailed::toInfoJson()); } +QMimeType LocationContent::type() const +{ + return QMimeDatabase().mimeTypeForData(geoUri.toLatin1()); +} + PlayableInfo::PlayableInfo(const QUrl& u, int fileSize, const QMimeType& mimeType, int duration, const QString& originalFilename) diff --git a/events/roommessageevent.h b/events/roommessageevent.h index 74e0defb..eef6b657 100644 --- a/events/roommessageevent.h +++ b/events/roommessageevent.h @@ -20,65 +20,11 @@ #include "event.h" -#include <QtCore/QUrl> -#include <QtCore/QMimeType> -#include <QtCore/QSize> +#include "eventcontent.h" namespace QMatrixClient { - namespace MessageEventContent - { - /** - * A base class for all content types that can be stored - * in a RoomMessageEvent - * - * Each content type class should have a constructor taking - * a QJsonObject and override fillJson() with an implementation - * that will fill the target QJsonObject with stored values. It is - * assumed but not required that a content object can also be created - * from plain data. fillJson() should only fill the main JSON object - * but not the "info" subobject if it exists for a certain content type; - * use \p InfoBase to de/serialize "info" parts with an optional URL - * on the top level. - */ - class Base - { - public: - virtual ~Base() = default; - - QJsonObject toJson() const; - - QMimeType mimeType; - - protected: - Base() = default; - explicit Base(const QMimeType& type) : mimeType(type) { } - - virtual void fillJson(QJsonObject* o) const = 0; - }; - - /** - * A base class for content types that have an "info" object in their - * JSON representation - * - * These include most multimedia types currently in the CS API spec. - * Derived classes should override fillInfoJson() to fill the "info" - * subobject, BUT NOT the main JSON object. Most but not all "info" - * classes (specifically, those deriving from UrlInfo) should also - * have a constructor that accepts two parameters, QUrl and QJsonObject, - * in order to load the URL+info part from JSON. - */ - class InfoBase: public Base - { - public: - QJsonObject toInfoJson() const; - - protected: - using Base::Base; - - virtual void fillInfoJson(QJsonObject* infoJson) const { } - }; - } // namespace MessageEventContent + namespace MessageEventContent = EventContent; // Back-compatibility /** * The event class corresponding to m.room.message events @@ -94,19 +40,19 @@ namespace QMatrixClient RoomMessageEvent(const QString& plainBody, const QString& jsonMsgType, - MessageEventContent::Base* content = nullptr) + EventContent::TypedBase* content = nullptr) : RoomEvent(Type::RoomMessage) , _msgtype(jsonMsgType), _plainBody(plainBody), _content(content) { } explicit RoomMessageEvent(const QString& plainBody, MsgType msgType = MsgType::Text, - MessageEventContent::Base* content = nullptr); + EventContent::TypedBase* content = nullptr); explicit RoomMessageEvent(const QJsonObject& obj); MsgType msgtype() const; QString rawMsgtype() const { return _msgtype; } const QString& plainBody() const { return _plainBody; } - const MessageEventContent::Base* content() const + const EventContent::TypedBase* content() const { return _content.data(); } QMimeType mimeType() const; @@ -117,18 +63,15 @@ namespace QMatrixClient private: QString _msgtype; QString _plainBody; - QScopedPointer<MessageEventContent::Base> _content; + QScopedPointer<EventContent::TypedBase> _content; REGISTER_ENUM(MsgType) }; using MessageEventType = RoomMessageEvent::MsgType; - namespace MessageEventContent + namespace EventContent { - // The below structures fairly follow CS spec 11.2.1.6. The overall - // set of attributes for each content types is a superset of the spec - // but specific aggregation structure is altered. See doc comments to - // each type for the list of available attributes. + // Additional event content types /** * Rich text content for m.text, m.emote, m.notice @@ -136,175 +79,22 @@ namespace QMatrixClient * Available fields: mimeType, body. The body can be either rich text * or plain text, depending on what mimeType specifies. */ - class TextContent: public Base + class TextContent: public TypedBase { public: TextContent(const QString& text, const QString& contentType); explicit TextContent(const QJsonObject& json); - void fillJson(QJsonObject* json) const override; + QMimeType type() const override { return mimeType; } + QMimeType mimeType; QString body; - }; - - /** - * Base class for content types that consist of a URL along with - * additional information - * - * All message types except the (hyper)text mentioned above and - * m.location fall under this category. - */ - class FileInfo: public InfoBase - { - public: - explicit FileInfo(const QUrl& u, int payloadSize = -1, - const QMimeType& mimeType = {}, - const QString& originalFilename = {}); - FileInfo(const QUrl& u, const QJsonObject& infoJson, - const QString& originalFilename = {}); - - QUrl url; - int payloadSize; - QString originalName; protected: void fillJson(QJsonObject* json) const override; - void fillInfoJson(QJsonObject* infoJson) const override; - }; - - /** - * A base class for image info types: image, thumbnail, video - * - * \tparam InfoT base info class; should derive from \p InfoBase - */ - template <class InfoT = FileInfo> - class ImageInfo : public InfoT - { - public: - explicit ImageInfo(const QUrl& u, int fileSize = -1, - QMimeType mimeType = {}, - const QSize& imageSize = {}) - : InfoT(u, fileSize, mimeType), imageSize(imageSize) - { } - ImageInfo(const QUrl& u, const QJsonObject& infoJson, - const QString& originalFilename = {}) - : InfoT(u, infoJson, originalFilename) - , imageSize(infoJson["w"].toInt(), infoJson["h"].toInt()) - { } - - void fillInfoJson(QJsonObject* infoJson) const /* override */ - { - InfoT::fillInfoJson(infoJson); - infoJson->insert("w", imageSize.width()); - infoJson->insert("h", imageSize.height()); - } - - QSize imageSize; - }; - - /** - * A base class for an info type that carries a thumbnail - * - * This class provides a means to save/load a thumbnail to/from "info" - * subobject of the JSON representation of a message; namely, - * "info/thumbnail_url" and "info/thumbnail_info" fields are used. - * - * \tparam InfoT base info class; should derive from \p InfoBase - */ - template <class InfoT = InfoBase> - class Thumbnailed : public InfoT - { - public: - template <typename... ArgTs> - explicit Thumbnailed(const ImageInfo<>& thumbnail, - ArgTs&&... infoArgs) - : InfoT(std::forward<ArgTs>(infoArgs)...) - , thumbnail(thumbnail) - { } - - explicit Thumbnailed(const QJsonObject& infoJson) - : thumbnail(infoJson["thumbnail_url"].toString(), - infoJson["thumbnail_info"].toObject()) - { } - - Thumbnailed(const QUrl& u, const QJsonObject& infoJson, - const QString& originalFilename = {}) - : InfoT(u, infoJson, originalFilename) - , thumbnail(infoJson["thumbnail_url"].toString(), - infoJson["thumbnail_info"].toObject()) - { } - - void fillInfoJson(QJsonObject* infoJson) const /* override */ - { - InfoT::fillInfoJson(infoJson); - infoJson->insert("thumbnail_url", thumbnail.url.toString()); - infoJson->insert("thumbnail_info", thumbnail.toInfoJson()); - } - - ImageInfo<> thumbnail; }; /** - * One more facility base class for content types that have a URL and - * additional info - * - * The assumed layout for types enabled by a combination of UrlInfo and - * UrlWith<> is the following: "url" and, optionally, "filename" in the - * top-level JSON and the rest of information inside the "info" subobject. - * - * \tparam InfoT base info class; should derive from \p UrlInfo or - * provide a constructor with a compatible signature - */ - template <class InfoT> // InfoT : public FileInfo - class UrlWith : public InfoT - { - public: - using InfoT::InfoT; - explicit UrlWith(const QJsonObject& json) - : InfoT(json["url"].toString(), json["info"].toObject(), - json["filename"].toString()) - { } - }; - - /** - * Content class for m.image - * - * Available fields: - * - corresponding to the top-level JSON: - * - url - * - filename (extension to the spec) - * - corresponding to the "info" subobject: - * - payloadSize ("size" in JSON) - * - mimeType ("mimetype" in JSON) - * - imageSize (QSize for a combination of "h" and "w" in JSON) - * - thumbnail.url ("thumbnail_url" in JSON) - * - corresponding to the "info/thumbnail_info" subobject: contents of - * thumbnail field, in the same vein as for the main image: - * - payloadSize - * - mimeType - * - imageSize - */ - using ImageContent = UrlWith<Thumbnailed<ImageInfo<>>>; - - /** - * Content class for m.file - * - * Available fields: - * - corresponding to the top-level JSON: - * - url - * - filename - * - corresponding to the "info" subobject: - * - payloadSize ("size" in JSON) - * - mimeType ("mimetype" in JSON) - * - thumbnail.url ("thumbnail_url" in JSON) - * - corresponding to the "info/thumbnail_info" subobject: - * - thumbnail.payloadSize - * - thumbnail.mimeType - * - thumbnail.imageSize (QSize for "h" and "w" in JSON) - */ - using FileContent = UrlWith<Thumbnailed<FileInfo>>; - - /** * Content class for m.location * * Available fields: @@ -317,16 +107,19 @@ namespace QMatrixClient * - thumbnail.mimeType * - thumbnail.imageSize */ - class LocationContent: public Thumbnailed<> + class LocationContent: public TypedBase, public Thumbnailed<> { public: LocationContent(const QString& geoUri, const ImageInfo<>& thumbnail); explicit LocationContent(const QJsonObject& json); - void fillJson(QJsonObject* o) const override; + QMimeType type() const override; QString geoUri; + + protected: + void fillJson(QJsonObject* o) const override; }; /** @@ -341,9 +134,10 @@ namespace QMatrixClient PlayableInfo(const QUrl& u, const QJsonObject& infoJson, const QString& originalFilename = {}); - void fillInfoJson(QJsonObject* infoJson) const override; - int duration; + + protected: + void fillInfoJson(QJsonObject* infoJson) const override; }; /** @@ -380,5 +174,5 @@ namespace QMatrixClient * - duration */ using AudioContent = UrlWith<PlayableInfo>; - } // namespace MessageEventContent + } // namespace EventContent } // namespace QMatrixClient diff --git a/events/roomnameevent.cpp b/events/roomnameevent.cpp deleted file mode 100644 index c202d17a..00000000 --- a/events/roomnameevent.cpp +++ /dev/null @@ -1,22 +0,0 @@ -/******************************************************************************
- * Copyright (C) 2015 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 "roomnameevent.h"
-
-using namespace QMatrixClient;
-
diff --git a/events/roomnameevent.h b/events/roomnameevent.h deleted file mode 100644 index bb823933..00000000 --- a/events/roomnameevent.h +++ /dev/null @@ -1,38 +0,0 @@ -/******************************************************************************
- * Copyright (C) 2015 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 "event.h"
-
-namespace QMatrixClient
-{
- class RoomNameEvent : public RoomEvent
- {
- public:
- explicit RoomNameEvent(const QJsonObject& obj)
- : RoomEvent(Type::RoomName, obj)
- , _name(contentJson()["name"].toString())
- { }
-
- QString name() const { return _name; }
-
- private:
- QString _name{};
- };
-} // namespace QMatrixClient
diff --git a/events/roomtopicevent.h b/events/roomtopicevent.h deleted file mode 100644 index 95ad0e04..00000000 --- a/events/roomtopicevent.h +++ /dev/null @@ -1,50 +0,0 @@ -/****************************************************************************** - * Copyright (C) 2015 Felix Rohrbach <kde@fxrh.de> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#pragma once - -#include "event.h" - -namespace QMatrixClient -{ - class RoomTopicEvent: public RoomEvent - { - public: - explicit RoomTopicEvent(const QString& topic) - : RoomEvent(Type::RoomTopic), _topic(topic) - { } - explicit RoomTopicEvent(const QJsonObject& obj) - : RoomEvent(Type::RoomTopic, obj) - , _topic(contentJson()["topic"].toString()) - { } - - QString topic() const { return _topic; } - - QJsonObject toJson() const - { - QJsonObject obj; - obj.insert("topic", _topic); - return obj; - } - - static constexpr const char* TypeId = "m.room.topic"; - - private: - QString _topic; - }; -} // namespace QMatrixClient diff --git a/events/simplestateevents.h b/events/simplestateevents.h new file mode 100644 index 00000000..d5841bdc --- /dev/null +++ b/events/simplestateevents.h @@ -0,0 +1,54 @@ +/****************************************************************************** + * Copyright (C) 2017 Kitsune Ral <kitsune-ral@users.sf.net> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#pragma once + +#include "event.h" + +#include "eventcontent.h" + +namespace QMatrixClient +{ +#define DECLARE_SIMPLE_STATE_EVENT(_Name, _TypeId, _EnumType, _ContentType, _ContentKey) \ + class _Name \ + : public StateEvent<EventContent::SimpleContent<_ContentType>> \ + { \ + public: \ + static constexpr const char* TypeId = _TypeId; \ + explicit _Name(const QJsonObject& obj) \ + : StateEvent(_EnumType, obj, #_ContentKey) \ + { } \ + template <typename T> \ + explicit _Name(T&& value) \ + : StateEvent(_EnumType, #_ContentKey, \ + std::forward<T>(value)) \ + { } \ + _ContentType _ContentKey() const { return content().value; } \ + }; + + DECLARE_SIMPLE_STATE_EVENT(RoomNameEvent, "m.room.name", + Event::Type::RoomName, QString, name) + DECLARE_SIMPLE_STATE_EVENT(RoomAliasesEvent, "m.room.aliases", + Event::Type::RoomAliases, QStringList, aliases) + DECLARE_SIMPLE_STATE_EVENT(RoomCanonicalAliasEvent, "m.room.canonical_alias", + Event::Type::RoomCanonicalAlias, QString, alias) + DECLARE_SIMPLE_STATE_EVENT(RoomTopicEvent, "m.room.topic", + Event::Type::RoomTopic, QString, topic) + DECLARE_SIMPLE_STATE_EVENT(EncryptionEvent, "m.room.encryption", + Event::Type::RoomEncryption, QString, algorithm) +} // namespace QMatrixClient diff --git a/events/typingevent.h b/events/typingevent.h index b12d224e..8c9551a4 100644 --- a/events/typingevent.h +++ b/events/typingevent.h @@ -27,6 +27,8 @@ namespace QMatrixClient class TypingEvent: public Event { public: + static constexpr const char* const TypeId = "m.typing"; + TypingEvent(const QJsonObject& obj); QStringList users() const { return _users; } diff --git a/events/unknownevent.cpp b/events/unknownevent.cpp deleted file mode 100644 index 1670ff1d..00000000 --- a/events/unknownevent.cpp +++ /dev/null @@ -1,64 +0,0 @@ -/****************************************************************************** - * Copyright (C) 2015 Felix Rohrbach <kde@fxrh.de> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "unknownevent.h" - -#include "logging.h" - -#include <QtCore/QJsonDocument> - -using namespace QMatrixClient; - -class UnknownEvent::Private -{ - public: - QString type; - QString content; -}; - -UnknownEvent::UnknownEvent() - : Event(EventType::Unknown) - , d(new Private) -{ -} - -UnknownEvent::~UnknownEvent() -{ - delete d; -} - -QString UnknownEvent::typeString() const -{ - return d->type; -} - -QString UnknownEvent::content() const -{ - return d->content; -} - -UnknownEvent* UnknownEvent::fromJson(const QJsonObject& obj) -{ - UnknownEvent* e = new UnknownEvent(); - e->parseJson(obj); - e->d->type = obj.value("type").toString(); - e->d->content = QString::fromUtf8(QJsonDocument(obj).toJson()); - qCDebug(EVENTS) << "UnknownEvent, JSON follows:"; - qCDebug(EVENTS) << formatJson << obj; - return e; -} diff --git a/events/unknownevent.h b/events/unknownevent.h deleted file mode 100644 index 51f2c4be..00000000 --- a/events/unknownevent.h +++ /dev/null @@ -1,40 +0,0 @@ -/****************************************************************************** - * Copyright (C) 2015 Felix Rohrbach <kde@fxrh.de> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#pragma once - -#include "event.h" - -namespace QMatrixClient -{ - class UnknownEvent: public Event - { - public: - UnknownEvent(); - virtual ~UnknownEvent(); - - QString typeString() const; - QString content() const; - - static UnknownEvent* fromJson(const QJsonObject& obj); - - private: - class Private; - Private* d; - }; -} |