File indexing completed on 2024-05-05 05:40:29

0001 /***************************************************************************
0002  *  Copyright (C) 2020 by Renaud Guezennec                               *
0003  *   http://www.rolisteam.org/contact                                      *
0004  *                                                                         *
0005  *   This software is free software; you can redistribute it and/or modify *
0006  *   it under the terms of the GNU General Public License as published by  *
0007  *   the Free Software Foundation; either version 2 of the License, or     *
0008  *   (at your option) any later version.                                   *
0009  *                                                                         *
0010  *   This program is distributed in the hope that it will be useful,       *
0011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
0012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
0013  *   GNU General Public License for more details.                          *
0014  *                                                                         *
0015  *   You should have received a copy of the GNU General Public License     *
0016  *   along with this program; if not, write to the                         *
0017  *   Free Software Foundation, Inc.,                                       *
0018  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
0019  ***************************************************************************/
0020 #include "model/messagemodel.h"
0021 
0022 #include <QDebug>
0023 #include <set>
0024 
0025 #include "data/person.h"
0026 #include "instantmessaging/messagefactory.h"
0027 #include "model/playermodel.h"
0028 
0029 namespace InstantMessaging
0030 {
0031 
0032 MessageModel::MessageModel(PlayerModel* playerModel, QObject* parent)
0033     : QAbstractListModel(parent), m_personModel(playerModel)
0034 {
0035 }
0036 
0037 MessageModel::~MessageModel()= default;
0038 
0039 int MessageModel::rowCount(const QModelIndex& parent) const
0040 {
0041     if(parent.isValid())
0042         return 0;
0043 
0044     return static_cast<int>(m_messages.size());
0045 }
0046 
0047 QVariant MessageModel::data(const QModelIndex& index, int role) const
0048 {
0049     if(!index.isValid())
0050         return QVariant();
0051 
0052     int item= role;
0053     if(role == Qt::DisplayRole)
0054         item= TextRole;
0055 
0056     std::set<int> map({MessageTypeRole, TextRole, TimeRole, OwnerRole, LocalRole, MessageRole, WriterRole,
0057                        OwnerNameRole, OwnerColorRole, WriterNameRole, WriterColorRole, ImageLinkRole});
0058 
0059     if(map.find(item) == map.end())
0060         return {};
0061 
0062     QVariant var;
0063     auto message= m_messages[static_cast<std::size_t>(index.row())].get();
0064 
0065     if(!message)
0066         return var;
0067 
0068     auto writer= m_personModel->personById(message->writer());
0069     auto owner= m_personModel->personById(message->owner());
0070 
0071     switch(item)
0072     {
0073     case MessageTypeRole:
0074         var= message->type();
0075         break;
0076     case TextRole:
0077         var= message->text();
0078         break;
0079     case MessageRole:
0080         var= QVariant::fromValue(message);
0081         break;
0082     case TimeRole:
0083         var= message->dateTime().toString("hh:mm");
0084         break;
0085     case LocalRole:
0086         var= (m_localId == message->owner());
0087         break;
0088     case WriterRole:
0089         var= message->writer();
0090         break;
0091     case OwnerRole:
0092         var= message->owner();
0093         break;
0094     case OwnerNameRole:
0095         var= owner ? owner->name() : tr("Invalid Person");
0096         break;
0097     case OwnerColorRole:
0098         var= owner ? owner->getColor() : Qt::gray;
0099         break;
0100     case WriterNameRole:
0101         var= writer ? writer->name() : tr("Invalid Person");
0102         break;
0103     case WriterColorRole:
0104         var= writer ? writer->getColor() : Qt::gray;
0105         break;
0106     case ImageLinkRole:
0107         var= message->imageLink();
0108         break;
0109     }
0110     return var;
0111 }
0112 
0113 QHash<int, QByteArray> MessageModel::roleNames() const
0114 {
0115     return QHash<int, QByteArray>({{MessageTypeRole, "type"},
0116                                    {TextRole, "text"},
0117                                    {TimeRole, "time"},
0118                                    {OwnerRole, "ownerId"},
0119                                    {OwnerNameRole, "ownerName"},
0120                                    {OwnerColorRole, "ownerColor"},
0121                                    {MessageRole, "message"},
0122                                    {WriterRole, "writerId"},
0123                                    {WriterNameRole, "writerName"},
0124                                    {WriterColorRole, "writerColor"},
0125                                    {LocalRole, "local"},
0126                                    {ImageLinkRole, "imageLink"}});
0127 }
0128 
0129 QString MessageModel::localId() const
0130 {
0131     return m_localId;
0132 }
0133 
0134 void MessageModel::setLocalId(const QString& localid)
0135 {
0136     if(m_localId == localid)
0137         return;
0138     m_localId= localid;
0139     emit localIdChanged(m_localId);
0140 }
0141 
0142 void MessageModel::addMessage(const QString& text, const QUrl& url, const QDateTime& time, const QString& owner,
0143                               const QString& writerId, InstantMessaging::MessageInterface::MessageType type)
0144 {
0145     auto msg= InstantMessaging::MessageFactory::createMessage(owner, writerId, time, type, text, url);
0146     if(!msg)
0147         return;
0148     addMessageInterface(msg);
0149     emit messageAdded(msg);
0150 }
0151 
0152 QModelIndex MessageModel::indexFromData(MessageInterface* msg)
0153 {
0154     auto it= std::find_if(std::begin(m_messages), std::end(m_messages),
0155                           [msg](const std::unique_ptr<MessageInterface>& index) { return msg == index.get(); });
0156 
0157     if(it == std::end(m_messages))
0158         return {};
0159 
0160     return index(std::distance(std::begin(m_messages), it), 0);
0161 }
0162 
0163 void MessageModel::addMessageInterface(MessageInterface* msg)
0164 {
0165     std::unique_ptr<MessageInterface> interface(msg);
0166 
0167     beginInsertRows(QModelIndex(), 0, 0);
0168     m_messages.insert(m_messages.begin(), std::move(interface));
0169     endInsertRows();
0170 
0171     connect(msg, &MessageInterface::imageLinkChanged, this, [this, msg]() {
0172         auto idx= indexFromData(msg);
0173         emit dataChanged(idx, idx, {ImageLinkRole});
0174     });
0175     connect(msg, &MessageInterface::textChanged, this, [this, msg]() {
0176         auto idx= indexFromData(msg);
0177         emit dataChanged(idx, idx, {TextRole});
0178     });
0179 
0180     if(msg->owner() != localId())
0181         emit unreadMessageChanged();
0182 }
0183 } // namespace InstantMessaging