File indexing completed on 2024-05-05 05:40:28
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/instantmessagingmodel.h" 0021 0022 #include <QDebug> 0023 #include <set> 0024 0025 #include "data/chatroom.h" 0026 #include "data/chatroomfactory.h" 0027 #include "instantmessaging/messageinterface.h" 0028 #include "model/playermodel.h" 0029 #include <diceparser_qobject/diceroller.h> 0030 0031 namespace InstantMessaging 0032 { 0033 namespace 0034 { 0035 bool isClosable(ChatRoom* chatroom) 0036 { 0037 return (chatroom->type() == ChatRoom::EXTRA 0038 || (chatroom->type() == ChatRoom::GLOBAL && chatroom->uuid() != QStringLiteral("global"))); 0039 } 0040 } // namespace 0041 InstantMessagingModel::InstantMessagingModel(DiceRoller* diceRoller, PlayerModel* playerModel, QObject* parent) 0042 : QAbstractListModel(parent), m_personModel(playerModel), m_diceParser(diceRoller) 0043 { 0044 } 0045 0046 InstantMessagingModel::~InstantMessagingModel()= default; 0047 0048 int InstantMessagingModel::rowCount(const QModelIndex& parent) const 0049 { 0050 if(parent.isValid()) 0051 return 0; 0052 0053 return static_cast<int>(m_chats.size()); 0054 } 0055 0056 QVariant InstantMessagingModel::data(const QModelIndex& index, int role) const 0057 { 0058 if(!index.isValid()) 0059 return QVariant(); 0060 0061 int item= role; 0062 if(role == Qt::DisplayRole) 0063 item= TitleRole; 0064 0065 std::set<int> map({TitleRole, ChatRole, RecipiantCountRole, IdRole, HasUnreadMessageRole, ClosableRole}); 0066 0067 if(map.find(item) == map.end()) 0068 return {}; 0069 0070 QVariant var; 0071 auto chatroom= m_chats[static_cast<std::size_t>(index.row())].get(); 0072 0073 switch(item) 0074 { 0075 case TitleRole: 0076 var= chatroom->title(); 0077 break; 0078 case ChatRole: 0079 var= QVariant::fromValue(chatroom); 0080 break; 0081 case IdRole: 0082 var= chatroom->uuid(); 0083 break; 0084 case TypeRole: 0085 var= chatroom->type(); 0086 break; 0087 case HasUnreadMessageRole: 0088 var= chatroom->unreadMessage(); 0089 break; 0090 case RecipiantCountRole: 0091 var= chatroom->recipiantCount(); 0092 break; 0093 case ClosableRole: 0094 var= isClosable(chatroom); 0095 break; 0096 } 0097 0098 return var; 0099 } 0100 0101 QHash<int, QByteArray> InstantMessagingModel::roleNames() const 0102 { 0103 return QHash<int, QByteArray>({{TitleRole, "title"}, 0104 {ChatRole, "chatroom"}, 0105 {IdRole, "id"}, 0106 {ClosableRole, "closable"}, 0107 {HasUnreadMessageRole, "unread"}, 0108 {RecipiantCountRole, "recipiantCount"}}); 0109 } 0110 0111 InstantMessaging::ChatRoom* InstantMessagingModel::globalChatRoom() const 0112 { 0113 Q_ASSERT(m_chats.size() > 0); 0114 return m_chats[0].get(); 0115 } 0116 0117 QString InstantMessagingModel::localId() const 0118 { 0119 return m_localId; 0120 } 0121 0122 bool InstantMessagingModel::unread() const 0123 { 0124 return std::any_of(std::begin(m_chats), std::end(m_chats), 0125 [](const std::unique_ptr<ChatRoom>& room) { return room->unreadMessage(); }); 0126 } 0127 0128 void InstantMessagingModel::insertGlobalChatroom(const QString& title, const QString& uuid) 0129 { 0130 addChatRoom(ChatRoomFactory::createChatRoom(title, QStringList(), uuid, InstantMessaging::ChatRoom::GLOBAL, 0131 localId(), m_personModel, this), 0132 !uuid.isEmpty()); 0133 } 0134 0135 void InstantMessagingModel::insertIndividualChatroom(const QString& playerId, const QString& playerName) 0136 { 0137 addChatRoom(ChatRoomFactory::createChatRoom(playerName, {playerId, localId()}, playerId, 0138 InstantMessaging::ChatRoom::SINGLEPLAYER, localId(), m_personModel, 0139 this)); 0140 } 0141 0142 void InstantMessagingModel::insertExtraChatroom(const QString& title, const QStringList& playerIds, bool remote, 0143 const QString& uuid) 0144 { 0145 addChatRoom(ChatRoomFactory::createChatRoom(title, playerIds, uuid, InstantMessaging::ChatRoom::EXTRA, localId(), 0146 m_personModel, this), 0147 remote); 0148 } 0149 0150 void InstantMessagingModel::addChatRoom(ChatRoom* room, bool remote) 0151 { 0152 if(!room) 0153 return; 0154 0155 std::unique_ptr<ChatRoom> chatroom(room); 0156 connect(this, &InstantMessagingModel::localIdChanged, chatroom.get(), &ChatRoom::setLocalId); 0157 0158 connect(room, &ChatRoom::unreadMessageChanged, this, 0159 [room, this]() 0160 { 0161 auto it= std::find_if(m_chats.begin(), m_chats.end(), 0162 [room](const std::unique_ptr<ChatRoom>& chatRoom) 0163 { return room == chatRoom.get(); }); 0164 auto idx= static_cast<int>(std::distance(m_chats.begin(), it)); 0165 emit dataChanged(index(idx, 0, QModelIndex()), index(idx, 0, QModelIndex()), 0166 {HasUnreadMessageRole, TitleRole}); 0167 emit unreadChanged(); 0168 }); 0169 chatroom->setLocalId(localId()); 0170 chatroom->setDiceParser(m_diceParser); 0171 0172 auto size= static_cast<int>(m_chats.size()); 0173 beginInsertRows(QModelIndex(), size, size); 0174 m_chats.push_back(std::move(chatroom)); 0175 endInsertRows(); 0176 0177 emit chatRoomCreated(room, remote); 0178 } 0179 0180 void InstantMessagingModel::setLocalId(const QString& id) 0181 { 0182 if(m_localId == id) 0183 return; 0184 m_localId= id; 0185 emit localIdChanged(m_localId); 0186 } 0187 0188 void InstantMessagingModel::addMessageIntoChatroom(MessageInterface* message, ChatRoom::ChatRoomType type, 0189 const QString& uuid) 0190 { // from network 0191 auto it= std::find_if(m_chats.begin(), m_chats.end(), 0192 [type, uuid, message](const std::unique_ptr<ChatRoom>& chatRoom) 0193 { 0194 bool val= false; 0195 if(chatRoom->uuid() == uuid) // global and Extra chatrom 0196 val= true; 0197 else if(type == ChatRoom::SINGLEPLAYER && type == chatRoom->type() 0198 && chatRoom->uuid() == message->owner()) // SinglePlayer chat room 0199 val= true; 0200 return val; 0201 }); 0202 0203 if(it == m_chats.end()) 0204 return; 0205 0206 (*it)->addMessageInterface(message); 0207 /* auto idx = std::distance(m_chats.begin(), it); 0208 emit dataChanged(index(idx, 0, QModelIndex()), index(idx, 0, QModelIndex()), 0209 {HasUnreadMessageRole, TitleRole});*/ 0210 } 0211 0212 void InstantMessagingModel::removePlayer(const QString& id) 0213 { 0214 auto it= std::find_if(m_chats.begin(), m_chats.end(), 0215 [id](const std::unique_ptr<ChatRoom>& chatRoom) 0216 { return (chatRoom->uuid() == id && ChatRoom::SINGLEPLAYER && chatRoom->type()); }); 0217 0218 if(it == m_chats.end()) 0219 return; 0220 0221 auto idx= static_cast<int>(std::distance(m_chats.begin(), it)); 0222 0223 beginRemoveRows(QModelIndex(), idx, idx); 0224 m_chats.erase(it); 0225 endRemoveRows(); 0226 } 0227 0228 void InstantMessagingModel::setDiceParser(DiceRoller* diceParser) 0229 { 0230 m_diceParser= diceParser; 0231 std::for_each(m_chats.begin(), m_chats.end(), 0232 [this](const std::unique_ptr<ChatRoom>& chatRoom) { chatRoom->setDiceParser(m_diceParser); }); 0233 } 0234 } // namespace InstantMessaging