From da8bb556dca628e20be732b4a30895010abcc9bf Mon Sep 17 00:00:00 2001 From: Kitsune Ral Date: Tue, 31 Oct 2017 13:12:33 +0300 Subject: Streamline EventContent hierarchy Two changes to make EventContent hierarchy easier to understand and use: - InfoBase is unbound from Base, and downstream classes use multiple inheritance to work "info" objects - MIME types are separated from Base into a separate TypedBase class because MIME typing is not common to all content kinds. --- events/eventcontent.cpp | 12 ++---------- events/eventcontent.h | 47 +++++++++++++++++++++++++++++++-------------- events/roommessageevent.cpp | 15 ++++++++++----- events/roommessageevent.h | 28 +++++++++++++++++---------- 4 files changed, 63 insertions(+), 39 deletions(-) (limited to 'events') diff --git a/events/eventcontent.cpp b/events/eventcontent.cpp index 205d404b..dcbccf08 100644 --- a/events/eventcontent.cpp +++ b/events/eventcontent.cpp @@ -37,6 +37,8 @@ QJsonObject InfoBase::toInfoJson() const 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) @@ -59,13 +61,3 @@ void FileInfo::fillInfoJson(QJsonObject* infoJson) const 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()); -} - diff --git a/events/eventcontent.h b/events/eventcontent.h index 2c8d7f3f..f9cdaf11 100644 --- a/events/eventcontent.h +++ b/events/eventcontent.h @@ -50,15 +50,16 @@ namespace QMatrixClient QJsonObject toJson() const; - QMimeType mimeType; - protected: - Base() = default; - explicit Base(const QMimeType& type) : mimeType(type) { } - virtual void fillJson(QJsonObject* o) const = 0; }; + class TypedBase: public Base + { + public: + virtual QMimeType type() const = 0; + }; + /** * A base class for content types that have an "info" object in their * JSON representation @@ -70,15 +71,20 @@ namespace QMatrixClient * have a constructor that accepts two parameters, QUrl and QJsonObject, * in order to load the URL+info part from JSON. */ - class InfoBase: public Base + class InfoBase { public: + virtual ~InfoBase() = default; + QJsonObject toInfoJson() const; + QMimeType mimeType; + protected: - using Base::Base; + InfoBase() = default; + explicit InfoBase(const QMimeType& type) : mimeType(type) { } - virtual void fillInfoJson(QJsonObject* /*infoJson*/) const { } + virtual void fillInfoJson(QJsonObject* /*infoJson*/) const = 0; }; // The below structures fairly follow CS spec 11.2.1.6. The overall @@ -105,7 +111,6 @@ namespace QMatrixClient QString originalName; protected: - void fillJson(QJsonObject* json) const override; void fillInfoJson(QJsonObject* infoJson) const override; }; @@ -129,14 +134,15 @@ namespace QMatrixClient , 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()); } - - QSize imageSize; }; /** @@ -172,14 +178,15 @@ namespace QMatrixClient 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()); } - - ImageInfo<> thumbnail; }; /** @@ -194,7 +201,7 @@ namespace QMatrixClient * provide a constructor with a compatible signature */ template // InfoT : public FileInfo - class UrlWith : public InfoT + class UrlWith : public TypedBase, public InfoT { public: using InfoT::InfoT; @@ -202,6 +209,18 @@ namespace QMatrixClient : 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()); + } }; /** diff --git a/events/roommessageevent.cpp b/events/roommessageevent.cpp index 82bd07b6..f06474e9 100644 --- a/events/roommessageevent.cpp +++ b/events/roommessageevent.cpp @@ -28,7 +28,7 @@ using namespace EventContent; using MsgType = RoomMessageEvent::MsgType; template -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 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"); } @@ -125,7 +125,7 @@ QJsonObject RoomMessageEvent::toJson() const } 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) @@ -170,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 b98f12d6..eef6b657 100644 --- a/events/roommessageevent.h +++ b/events/roommessageevent.h @@ -40,19 +40,19 @@ namespace QMatrixClient RoomMessageEvent(const QString& plainBody, const QString& jsonMsgType, - EventContent::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, - EventContent::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 EventContent::Base* content() const + const EventContent::TypedBase* content() const { return _content.data(); } QMimeType mimeType() const; @@ -63,7 +63,7 @@ namespace QMatrixClient private: QString _msgtype; QString _plainBody; - QScopedPointer _content; + QScopedPointer _content; REGISTER_ENUM(MsgType) }; @@ -79,15 +79,19 @@ 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; + + protected: + void fillJson(QJsonObject* json) const override; }; /** @@ -103,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; }; /** @@ -127,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; }; /** -- cgit v1.2.3