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

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 "controller/instantmessagingcontroller.h"
0021 
0022 #include <QJSEngine>
0023 #include <QQmlEngine>
0024 #include <QQuickStyle>
0025 
0026 #include "common_qml/theme.h"
0027 #include "data/chatroom.h"
0028 #include "data/player.h"
0029 #include "diceparser_qobject/diceroller.h"
0030 #include "instantmessaging/textwritercontroller.h"
0031 #include "model/chatroomsplittermodel.h"
0032 #include "model/filterinstantmessagingmodel.h"
0033 #include "model/instantmessagingmodel.h"
0034 #include "model/messagemodel.h"
0035 #include "network/receiveevent.h"
0036 #include "updater/media/instantmessagingupdater.h"
0037 
0038 void registerType()
0039 {
0040     // TODO Move that into view? or define module with Qt6/cmake syntax
0041     static bool registered= false;
0042 
0043     if(registered)
0044         return;
0045 
0046     qDebug() << "registerType 2";
0047     qRegisterMetaType<InstantMessaging::FilterInstantMessagingModel*>("FilterInstantMessagingModel*");
0048     qRegisterMetaType<InstantMessaging::MessageModel*>("MessageModel*");
0049     qRegisterMetaType<LocalPersonModel*>("LocalPersonModel*");
0050     qRegisterMetaType<PlayerModel*>("PlayerModel*");
0051     qRegisterMetaType<InstantMessaging::ChatRoom*>("ChatRoom*");
0052     qRegisterMetaType<customization::Theme*>("customization::Theme*");
0053     qRegisterMetaType<customization::StyleSheet*>("customization::StyleSheet*");
0054     qRegisterMetaType<InstantMessaging::ChatroomSplitterModel*>("ChatroomSplitterModel*");
0055 
0056     qmlRegisterAnonymousType<InstantMessagingController>("InstantMessagingController", 1);
0057     qmlRegisterAnonymousType<InstantMessaging::FilterInstantMessagingModel>("FilterInstantMessagingModel", 1);
0058     qmlRegisterAnonymousType<InstantMessaging::MessageModel>("MessageModel", 1);
0059     qmlRegisterAnonymousType<LocalPersonModel>("LocalPersonModel", 1);
0060     qmlRegisterAnonymousType<PlayerModel>("PlayerModel", 1);
0061     qmlRegisterAnonymousType<InstantMessaging::ChatroomSplitterModel>("ChatroomSplitterModel", 1);
0062     qmlRegisterUncreatableType<InstantMessaging::ChatRoom>("InstantMessaging", 1, 0, "ChatRoom",
0063                                                            "ChatRoom can't be created.");
0064     qmlRegisterType<InstantMessaging::TextWriterController>("InstantMessaging", 1, 0, "TextWriterController");
0065     qmlRegisterSingletonType<customization::Theme>("Customization", 1, 0, "Theme",
0066                                                    [](QQmlEngine* engine, QJSEngine*) -> QObject*
0067                                                    {
0068                                                        auto instead= customization::Theme::instance();
0069                                                        engine->setObjectOwnership(instead, QQmlEngine::CppOwnership);
0070                                                        return instead;
0071                                                    });
0072 
0073     qmlRegisterUncreatableType<InstantMessaging::MessageInterface>("Customization", 1, 0, "MessageInterface",
0074                                                                    "Not creatable as it is an enum type.");
0075 
0076     registered= true;
0077 }
0078 
0079 InstantMessagingController::InstantMessagingController(DiceRoller* diceRoller, PlayerModel* model, QObject* parent)
0080     : AbstractControllerInterface(parent)
0081     , m_localPersonModel(new LocalPersonModel)
0082     , m_updater(new InstantMessaging::InstantMessagingUpdater)
0083     , m_model(new InstantMessaging::InstantMessagingModel(diceRoller, model))
0084     , m_players(model)
0085     , m_diceParser(diceRoller)
0086 {
0087     ReceiveEvent::registerNetworkReceiver(NetMsg::InstantMessageCategory, this);
0088     registerType();
0089     addChatroomSplitterModel();
0090 
0091     m_localPersonModel->setSourceModel(m_players);
0092 
0093     connect(m_model.get(), &InstantMessaging::InstantMessagingModel::unreadChanged, this,
0094             &InstantMessagingController::unreadChanged);
0095 
0096     connect(m_model.get(), &InstantMessaging::InstantMessagingModel::chatRoomCreated, this,
0097             [this](InstantMessaging::ChatRoom* room, bool remote) { m_updater->addChatRoom(room, remote); });
0098     connect(m_model.get(), &InstantMessaging::InstantMessagingModel::localIdChanged, this,
0099             &InstantMessagingController::localIdChanged);
0100     connect(m_players, &PlayerModel::playerJoin, this,
0101             [this](Player* player)
0102             {
0103                 if(nullptr == player)
0104                     return;
0105                 if(player->uuid() == localId())
0106                     return;
0107 
0108                 m_model->insertIndividualChatroom(player->uuid(), player->name());
0109             });
0110 
0111     connect(m_players, &PlayerModel::playerLeft, this,
0112             [this](Player* player)
0113             {
0114                 if(nullptr == player)
0115                     return;
0116 
0117                 m_model->removePlayer(player->uuid());
0118             });
0119 
0120     m_model->insertGlobalChatroom(tr("Global"), QStringLiteral("global"));
0121 }
0122 
0123 InstantMessagingController::~InstantMessagingController()= default;
0124 
0125 InstantMessaging::ChatroomSplitterModel* InstantMessagingController::mainModel() const
0126 {
0127     Q_ASSERT(m_splitterModels.size() > 0);
0128     return m_splitterModels[0].get();
0129 }
0130 
0131 InstantMessaging::ChatRoom* InstantMessagingController::globalChatroom() const
0132 {
0133     return m_model->globalChatRoom();
0134 }
0135 
0136 PlayerModel* InstantMessagingController::playerModel() const
0137 {
0138     return m_players;
0139 }
0140 
0141 LocalPersonModel* InstantMessagingController::localPersonModel() const
0142 {
0143     return m_localPersonModel.get();
0144 }
0145 
0146 QString InstantMessagingController::localId() const
0147 {
0148     return m_model->localId();
0149 }
0150 
0151 bool InstantMessagingController::nightMode() const
0152 {
0153     return m_nightMode;
0154 }
0155 
0156 bool InstantMessagingController::visible() const
0157 {
0158     return m_visible;
0159 }
0160 
0161 bool InstantMessagingController::unread() const
0162 {
0163     return m_model->unread();
0164 }
0165 
0166 void InstantMessagingController::openLink(const QString& link)
0167 {
0168     qDebug() << "open link" << link;
0169     emit openWebPage(link);
0170 }
0171 
0172 void InstantMessagingController::setDiceParser(DiceRoller* diceParser)
0173 {
0174     m_model->setDiceParser(diceParser);
0175 }
0176 
0177 void InstantMessagingController::setVisible(bool b)
0178 {
0179     if(b == m_visible)
0180         return;
0181     m_visible= b;
0182     emit visibleChanged(m_visible);
0183 }
0184 
0185 void InstantMessagingController::setGameController(GameController*) {}
0186 
0187 NetWorkReceiver::SendType InstantMessagingController::processMessage(NetworkMessageReader* msg)
0188 {
0189     NetWorkReceiver::SendType type= NetWorkReceiver::AllExceptSender;
0190     switch(msg->action())
0191     {
0192     case NetMsg::InstantMessageAction:
0193         m_updater->addMessageToModel(m_model.get(), msg);
0194         break;
0195     case NetMsg::AddChatroomAction:
0196         m_updater->readChatroomToModel(m_model.get(), msg);
0197         break;
0198     default:
0199         break;
0200     }
0201     return type;
0202 }
0203 
0204 void InstantMessagingController::detach(const QString& id, int index)
0205 {
0206     Q_UNUSED(index);
0207     Q_UNUSED(id);
0208 }
0209 
0210 void InstantMessagingController::reattach(const QString& id, int index)
0211 {
0212     Q_UNUSED(index);
0213     Q_UNUSED(id);
0214 }
0215 
0216 void InstantMessagingController::splitScreen(const QString& id, int index)
0217 {
0218     if(index >= static_cast<int>(m_splitterModels.size()) || index < 0)
0219         return;
0220 
0221     auto model= m_splitterModels.at(static_cast<std::size_t>(index)).get();
0222     model->addFilterModel(m_model.get(), {id}, false);
0223 }
0224 
0225 void InstantMessagingController::setLocalId(const QString& id)
0226 {
0227     m_model->setLocalId(id);
0228 }
0229 
0230 void InstantMessagingController::addExtraChatroom(const QString& title, bool everyone, const QVariantList& recipiant)
0231 {
0232     if(everyone)
0233         m_model->insertGlobalChatroom(title);
0234     else
0235     {
0236         QStringList ids;
0237         ids.reserve(recipiant.size());
0238         std::transform(recipiant.begin(), recipiant.end(), std::back_inserter(ids),
0239                        [](const QVariant& variant) { return variant.toString(); });
0240 
0241         m_model->insertExtraChatroom(title, ids, false);
0242     }
0243 }
0244 
0245 void InstantMessagingController::setNightMode(bool mode)
0246 {
0247     if(m_nightMode == mode)
0248         return;
0249     m_nightMode= mode;
0250     emit nightModeChanged(m_nightMode);
0251 }
0252 
0253 void InstantMessagingController::addChatroomSplitterModel()
0254 {
0255     std::unique_ptr<InstantMessaging::ChatroomSplitterModel> model(new InstantMessaging::ChatroomSplitterModel);
0256     model->addFilterModel(m_model.get());
0257     m_splitterModels.push_back(std::move(model));
0258 }