diff options
author | Kitsune Ral <Kitsune-Ral@users.sf.net> | 2018-03-31 13:16:02 +0900 |
---|---|---|
committer | Kitsune Ral <Kitsune-Ral@users.sf.net> | 2018-03-31 14:23:55 +0900 |
commit | efeb50a46ad824aa258472f6ac8da74810f05a55 (patch) | |
tree | a89c6f35d56986c60e73f870530c9d6ee0527e6d /lib/events/roommessageevent.cpp | |
parent | 29093379b707bfe620234c2968b37aa86666542a (diff) | |
download | libquotient-efeb50a46ad824aa258472f6ac8da74810f05a55.tar.gz libquotient-efeb50a46ad824aa258472f6ac8da74810f05a55.zip |
Move source files to a separate folder
It's been long overdue to separate them from the rest of the stuff (docs etc.). Also, this allows installing to a directory within the checked out git tree (say, ./install/, similar to ./build/).
Diffstat (limited to 'lib/events/roommessageevent.cpp')
-rw-r--r-- | lib/events/roommessageevent.cpp | 193 |
1 files changed, 193 insertions, 0 deletions
diff --git a/lib/events/roommessageevent.cpp b/lib/events/roommessageevent.cpp new file mode 100644 index 00000000..dec0ca50 --- /dev/null +++ b/lib/events/roommessageevent.cpp @@ -0,0 +1,193 @@ +/****************************************************************************** + * 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 "roommessageevent.h" + +#include "logging.h" + +#include <QtCore/QMimeDatabase> + +using namespace QMatrixClient; +using namespace EventContent; + +using MsgType = RoomMessageEvent::MsgType; + +template <typename ContentT> +TypedBase* make(const QJsonObject& json) +{ + return new ContentT(json); +} + +struct MsgTypeDesc +{ + QString jsonType; + MsgType enumType; + TypedBase* (*maker)(const QJsonObject&); +}; + +const std::vector<MsgTypeDesc> msgTypes = + { { QStringLiteral("m.text"), MsgType::Text, make<TextContent> } + , { QStringLiteral("m.emote"), MsgType::Emote, make<TextContent> } + , { QStringLiteral("m.notice"), 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; }); + if (it != msgTypes.end()) + return it->jsonType; + + return {}; +} + +MsgType jsonToMsgType(const QString& jsonType) +{ + auto it = std::find_if(msgTypes.begin(), msgTypes.end(), + [=](const MsgTypeDesc& mtd) { return mtd.jsonType == jsonType; }); + if (it != msgTypes.end()) + return it->enumType; + + return MsgType::Unknown; +} + +RoomMessageEvent::RoomMessageEvent(const QString& plainBody, + MsgType msgType, TypedBase* content) + : RoomMessageEvent(plainBody, msgTypeToJson(msgType), content) +{ } + +RoomMessageEvent::RoomMessageEvent(const QJsonObject& obj) + : RoomEvent(Type::RoomMessage, obj), _content(nullptr) +{ + if (isRedacted()) + return; + const QJsonObject content = contentJson(); + if ( content.contains("msgtype") && content.contains("body") ) + { + _plainBody = content["body"].toString(); + + _msgtype = content["msgtype"].toString(); + for (auto mt: msgTypes) + if (mt.jsonType == _msgtype) + _content.reset(mt.maker(content)); + + if (!_content) + { + qCWarning(EVENTS) << "RoomMessageEvent: couldn't load content," + << " full content dump follows"; + qCWarning(EVENTS) << formatJson << content; + } + } + else + { + qCWarning(EVENTS) << "No body or msgtype in room message event"; + qCWarning(EVENTS) << formatJson << obj; + } +} + +RoomMessageEvent::MsgType RoomMessageEvent::msgtype() const +{ + return jsonToMsgType(_msgtype); +} + +QMimeType RoomMessageEvent::mimeType() const +{ + return _content ? _content->type() : + QMimeDatabase().mimeTypeForName("text/plain"); +} + +bool RoomMessageEvent::hasTextContent() const +{ + return content() && + (msgtype() == MsgType::Text || msgtype() == MsgType::Emote || + msgtype() == MsgType::Notice); // FIXME: Unbind from specific msgtypes +} + +bool RoomMessageEvent::hasFileContent() const +{ + return content() && content()->fileInfo(); +} + +bool RoomMessageEvent::hasThumbnail() const +{ + return content() && content()->thumbnailInfo(); +} + +QJsonObject RoomMessageEvent::toJson() const +{ + QJsonObject obj = _content ? _content->toJson() : QJsonObject(); + obj.insert("msgtype", msgTypeToJson(msgtype())); + obj.insert("body", plainBody()); + return obj; +} + +TextContent::TextContent(const QString& text, const QString& contentType) + : mimeType(QMimeDatabase().mimeTypeForName(contentType)), body(text) +{ } + +TextContent::TextContent(const QJsonObject& json) +{ + QMimeDatabase db; + + // Special-casing the custom matrix.org's (actually, Riot's) way + // of sending HTML messages. + if (json["format"].toString() == "org.matrix.custom.html") + { + mimeType = db.mimeTypeForName("text/html"); + body = json["formatted_body"].toString(); + } else { + // Falling back to plain text, as there's no standard way to describe + // rich text in messages. + mimeType = db.mimeTypeForName("text/plain"); + body = json["body"].toString(); + } +} + +void TextContent::fillJson(QJsonObject* json) const +{ + Q_ASSERT(json); + json->insert("format", QStringLiteral("org.matrix.custom.html")); + json->insert("formatted_body", body); +} + +LocationContent::LocationContent(const QString& geoUri, const ImageInfo& thumbnail) + : geoUri(geoUri), thumbnail(thumbnail) +{ } + +LocationContent::LocationContent(const QJsonObject& json) + : TypedBase(json) + , geoUri(json["geo_uri"].toString()) + , thumbnail(json["info"].toObject()) +{ } + +QMimeType LocationContent::type() const +{ + return QMimeDatabase().mimeTypeForData(geoUri.toLatin1()); +} + +void LocationContent::fillJson(QJsonObject* o) const +{ + Q_ASSERT(o); + o->insert("geo_uri", geoUri); + o->insert("info", toInfoJson(thumbnail)); +} |