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