/* * Squawk messenger. * Copyright (C) 2019 Yury Gubich * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef MESSAGEFEED_H #define MESSAGEFEED_H #include #include #include #include #include #include #include #include #include #include #include namespace Models { class Element; struct Attachment; struct Edition; class MessageFeed : public QAbstractListModel { Q_OBJECT public: enum SyncState { incomplete, syncing, complete }; MessageFeed(const Element* rosterItem, QObject *parent = nullptr); ~MessageFeed(); void addMessage(const Shared::Message& msg); void changeMessage(const QString& id, const QMap& data); void removeMessage(const QString& id); Shared::Message getMessage(const QString& id); QModelIndex modelIndexById(const QString& id) const; QModelIndex modelIndexByTime(const QString& id, const QDateTime& time) const; QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const override; int rowCount(const QModelIndex& parent = QModelIndex()) const override; bool canFetchMore(const QModelIndex & parent) const override; void fetchMore(const QModelIndex & parent) override; QHash roleNames() const override; QModelIndex index(int row, int column, const QModelIndex & parent) const override; void responseArchive(const std::list list, bool last); void downloadAttachment(const QString& messageId); bool registerUpload(const QString& messageId); void reportLocalPathInvalid(const QString& messageId); unsigned int unreadMessagesCount() const; bool markMessageAsRead(const QString& id) const; void fileProgress(const QString& messageId, qreal value, bool up); void fileError(const QString& messageId, const QString& error, bool up); void fileComplete(const QString& messageId, bool up); void incrementObservers(); void decrementObservers(); SyncState getSyncState() const; void requestLatestMessages(); //this method is used by Models::Contact to request latest messages after reconnection signals: void requestArchive(const QString& before); void fileDownloadRequest(const QString& url); void unreadMessagesCountChanged() const; void newMessage(const Shared::Message& msg); void unnoticedMessage(const Shared::Message& msg); void localPathInvalid(const QString& path); void syncStateChange(SyncState state); public: enum MessageRoles { Text = Qt::UserRole + 1, Sender, Date, DeliveryState, Correction, SentByMe, Avatar, Attach, Id, Error, Bulk }; class NotFound: public Utils::Exception { public: NotFound(const std::string& k, const std::string& j, const std::string& acc):Exception(), key(k), jid(j), account(acc){} std::string getMessage() const { return "Message with id " + key + " wasn't found in messageFeed " + account + " of the chat with " + jid; } private: std::string key; std::string jid; std::string account; }; protected: bool sentByMe(const Shared::Message& msg) const; Attachment fillAttach(const Shared::Message& msg) const; Edition fillCorrection(const Shared::Message& msg) const; std::set detectChanges(const Shared::Message& msg, const QMap& data) const; private: //tags struct id {}; struct time {}; typedef boost::multi_index_container< Shared::Message*, boost::multi_index::indexed_by< boost::multi_index::ordered_unique< boost::multi_index::tag, boost::multi_index::const_mem_fun< Shared::Message, QString, &Shared::Message::getId > >, boost::multi_index::ranked_non_unique< boost::multi_index::tag