File indexing completed on 2024-05-19 05:40:36

0001 /***************************************************************************
0002  *  Copyright (C) 2021 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/view_controller/selectconnprofilecontroller.h"
0021 
0022 #include <QDebug>
0023 #include <QtConcurrent>
0024 
0025 #include "network/characterdatamodel.h"
0026 #include "network/connectionprofile.h"
0027 #include "worker/fileserializer.h"
0028 #include "worker/utilshelper.h"
0029 
0030 SelectConnProfileController::SelectConnProfileController(ProfileModel* model, QObject* parent)
0031     : QObject{parent}, m_profileModel{model}, m_characterModel{new CharacterDataModel}
0032 {
0033 
0034     auto connectProfile= [this](ConnectionProfile* prof)
0035     {
0036         if(prof == nullptr)
0037             return;
0038 
0039         connect(prof, &ConnectionProfile::gmChanged, this,
0040                 [prof, this]()
0041                 {
0042                     if(!prof->isGM() && (prof->characterCount() == 0))
0043                     {
0044                         connection::CharacterData data({QUuid::createUuid().toString(),
0045                                                         QObject::tr("Unknown Character"), Qt::red, "",
0046                                                         QHash<QString, QVariant>()});
0047                         m_characterModel->addCharacter(data);
0048                     }
0049                 });
0050 
0051         auto updateCharacters= [prof]()
0052         { prof->setCharactersValid(helper::utils::hasValidCharacter(prof->characters(), prof->isGM())); };
0053         connect(prof, &ConnectionProfile::characterCountChanged, this, updateCharacters);
0054         connect(prof, &ConnectionProfile::characterChanged, this, updateCharacters);
0055 
0056         auto updatePlayerInfo= [prof]()
0057         {
0058             prof->setPlayerInfoValid(prof->playerColor().isValid() && !prof->playerName().isEmpty()
0059                                      && helper::utils::isSquareImage(prof->playerAvatar()));
0060         };
0061         connect(prof, &ConnectionProfile::playerAvatarChanged, this, updatePlayerInfo);
0062         connect(prof, &ConnectionProfile::playerColorChanged, this, updatePlayerInfo);
0063         connect(prof, &ConnectionProfile::playerNameChanged, this, updatePlayerInfo);
0064 
0065         auto updateCampaign= [prof]()
0066         {
0067             prof->setCampaignInfoValid(
0068                 prof->isGM() ? campaign::FileSerializer::isValidCampaignDirectory(prof->campaignPath()) : true);
0069         };
0070         connect(prof, &ConnectionProfile::gmChanged, this, updateCampaign);
0071         connect(prof, &ConnectionProfile::campaignPathChanged, this, updateCampaign);
0072 
0073         updateCharacters();
0074         updateCampaign();
0075         updatePlayerInfo();
0076     };
0077 
0078     connect(m_profileModel, &ProfileModel::profileAdded, this, connectProfile);
0079 
0080     if(m_profileModel)
0081     {
0082         for(int i= 0; i < m_profileModel->rowCount(); ++i)
0083         {
0084             auto prof= m_profileModel->getProfile(i);
0085             connectProfile(prof);
0086         }
0087     }
0088     connect(this, &SelectConnProfileController::connectionStateChanged, this,
0089             [this](ConnectionState newState, ConnectionState oldState)
0090             {
0091                 if(newState == ConnectionState::IDLE)
0092                 {
0093                     emit stopConnecting();
0094                 }
0095                 if(oldState == ConnectionState::LOADING && newState == ConnectionState::LOADED)
0096                 {
0097                     emit startConnect();
0098                 }
0099             });
0100 
0101     if(m_profileModel && m_profileModel->rowCount() > 0)
0102         setCurrentProfileIndex(0);
0103 }
0104 SelectConnProfileController::~SelectConnProfileController()= default;
0105 
0106 ProfileModel* SelectConnProfileController::profileModel() const
0107 {
0108     return m_profileModel;
0109 }
0110 
0111 int SelectConnProfileController::currentProfileIndex() const
0112 {
0113     return m_currentProfileIndex;
0114 }
0115 
0116 QString SelectConnProfileController::profileName() const
0117 {
0118     return currentProfile() ? currentProfile()->profileTitle() : QString();
0119 }
0120 
0121 QString SelectConnProfileController::playerName() const
0122 {
0123     return currentProfile() ? currentProfile()->playerName() : QString();
0124 }
0125 
0126 QColor SelectConnProfileController::playerColor() const
0127 {
0128     return currentProfile() ? currentProfile()->playerColor() : QColor();
0129 }
0130 
0131 QByteArray SelectConnProfileController::playerAvatar() const
0132 {
0133     return currentProfile() ? currentProfile()->playerAvatar() : QByteArray();
0134 }
0135 
0136 CharacterDataModel* SelectConnProfileController::characterModel() const
0137 {
0138     return m_characterModel.get();
0139 }
0140 QString SelectConnProfileController::campaignPath() const
0141 {
0142     return currentProfile() ? currentProfile()->campaignPath() : QString();
0143 }
0144 
0145 SelectConnProfileController::ConnectionState SelectConnProfileController::connectionState() const
0146 {
0147     return m_connectionState;
0148 }
0149 
0150 bool SelectConnProfileController::validCampaignPath() const
0151 {
0152     return currentProfile() ? currentProfile()->campaignInfoValid() : false;
0153 }
0154 bool SelectConnProfileController::isGameMaster() const
0155 {
0156     return currentProfile() ? currentProfile()->isGM() : false;
0157 }
0158 bool SelectConnProfileController::isServer() const
0159 {
0160     return currentProfile() ? currentProfile()->isServer() : false;
0161 }
0162 QString SelectConnProfileController::address() const
0163 {
0164     return currentProfile() ? currentProfile()->address() : QString();
0165 }
0166 int SelectConnProfileController::port() const
0167 {
0168     return currentProfile() ? currentProfile()->port() : 6660;
0169 }
0170 QString SelectConnProfileController::errorMsg() const
0171 {
0172     return m_error;
0173 }
0174 
0175 bool SelectConnProfileController::canConnect() const
0176 {
0177     return currentProfile() ? currentProfile()->valid() : false;
0178 }
0179 
0180 ConnectionProfile* SelectConnProfileController::currentProfile() const
0181 {
0182     if(m_profileModel.isNull())
0183         return nullptr;
0184     return m_profileModel->getProfile(m_currentProfileIndex);
0185 }
0186 
0187 // setter
0188 void SelectConnProfileController::setCurrentProfileIndex(int i)
0189 {
0190     if(i == m_currentProfileIndex)
0191         return;
0192     if(currentProfile())
0193         disconnect(currentProfile(), 0, this, 0);
0194     m_currentProfileIndex= i;
0195     auto prof= currentProfile();
0196     if(prof)
0197     {
0198         connect(prof, &ConnectionProfile::titleChanged, this, &SelectConnProfileController::profileNameChanged);
0199         connect(prof, &ConnectionProfile::playerNameChanged, this, &SelectConnProfileController::playerNameChanged);
0200         connect(prof, &ConnectionProfile::playerColorChanged, this, &SelectConnProfileController::playerColorChanged);
0201         connect(prof, &ConnectionProfile::playerAvatarChanged, this, &SelectConnProfileController::playerAvatarChanged);
0202         connect(prof, &ConnectionProfile::portChanged, this, &SelectConnProfileController::portChanged);
0203         connect(prof, &ConnectionProfile::addressChanged, this, &SelectConnProfileController::addressChanged);
0204         connect(prof, &ConnectionProfile::serverChanged, this, &SelectConnProfileController::isServerChanged);
0205         connect(prof, &ConnectionProfile::gmChanged, this, &SelectConnProfileController::isGameMasterChanged);
0206         connect(prof, &ConnectionProfile::passwordChanged, this, &SelectConnProfileController::passwordChanged);
0207         connect(prof, &ConnectionProfile::campaignPathChanged, this, &SelectConnProfileController::campaignPathChanged);
0208         connect(prof, &ConnectionProfile::validChanged, this, &SelectConnProfileController::canConnectChanged);
0209         m_characterModel->setProfile(prof);
0210     }
0211     setConnectionState(ConnectionState::IDLE);
0212     emit currentProfileIndexChanged();
0213     emit profileNameChanged();
0214     emit playerNameChanged();
0215     emit playerColorChanged();
0216     emit playerAvatarChanged();
0217     emit portChanged();
0218     emit addressChanged();
0219     emit isServerChanged();
0220     emit isGameMasterChanged();
0221     emit passwordChanged();
0222     emit campaignPathChanged();
0223     emit canConnectChanged();
0224 
0225     // updateCanConnect();
0226 }
0227 void SelectConnProfileController::setConnectionState(ConnectionState state)
0228 {
0229     if(m_connectionState == state)
0230         return;
0231     auto old= m_connectionState;
0232     m_connectionState= state;
0233     emit connectionStateChanged(m_connectionState, old);
0234 }
0235 
0236 void SelectConnProfileController::setProfileName(const QString& val)
0237 {
0238     if(currentProfile())
0239         currentProfile()->setProfileTitle(val);
0240 }
0241 void SelectConnProfileController::setPlayerName(const QString& val)
0242 {
0243     if(currentProfile())
0244         currentProfile()->setPlayerName(val);
0245 }
0246 void SelectConnProfileController::setPlayerColor(const QColor& val)
0247 {
0248     if(currentProfile())
0249         currentProfile()->setPlayerColor(val);
0250 }
0251 void SelectConnProfileController::setPlayerAvatar(const QByteArray& val)
0252 {
0253     if(currentProfile())
0254         currentProfile()->setPlayerAvatar(val);
0255 }
0256 void SelectConnProfileController::setIsGameMaster(bool val)
0257 {
0258     if(currentProfile())
0259         currentProfile()->setGm(val);
0260 }
0261 void SelectConnProfileController::setIsServer(bool val)
0262 {
0263     if(currentProfile())
0264         currentProfile()->setServerMode(val);
0265 }
0266 void SelectConnProfileController::setAddress(const QString& val)
0267 {
0268     if(currentProfile())
0269         currentProfile()->setAddress(val);
0270 }
0271 void SelectConnProfileController::setPort(int val)
0272 {
0273     if(currentProfile())
0274         currentProfile()->setPort(val);
0275 }
0276 void SelectConnProfileController::setErrorMsg(const QString& val)
0277 {
0278     if(m_error == val)
0279         return;
0280     m_error= val;
0281     emit errorMsgChanged();
0282 }
0283 
0284 void SelectConnProfileController::setCampaignPath(const QString& val)
0285 {
0286     if(currentProfile())
0287         currentProfile()->setCampaignPath(val);
0288 }
0289 
0290 void SelectConnProfileController::addCharacter()
0291 {
0292     m_characterModel->insertCharacter();
0293 }
0294 
0295 void SelectConnProfileController::removeCharacter(int idx)
0296 {
0297     m_characterModel->removeCharacter(idx);
0298 }
0299 
0300 void SelectConnProfileController::editCharacterName(int idx, const QString& data)
0301 {
0302     m_characterModel->setName(idx, data);
0303 }
0304 
0305 void SelectConnProfileController::editCharacterColor(int idx, const QColor& color)
0306 {
0307     m_characterModel->setColor(idx, color);
0308 }
0309 
0310 void SelectConnProfileController::editCharacterAvatar(int idx, const QByteArray& array)
0311 {
0312     m_characterModel->setAvatar(idx, array);
0313 }
0314 
0315 void SelectConnProfileController::addProfile()
0316 {
0317     if(!m_profileModel)
0318         return;
0319     m_profileModel->appendProfile();
0320 }
0321 void SelectConnProfileController::removeProfile(int idx)
0322 {
0323     if(!m_profileModel)
0324         return;
0325     m_profileModel->removeProfile(idx);
0326 }
0327 void SelectConnProfileController::cloneProfile(int idx)
0328 {
0329     if(!m_profileModel)
0330         return;
0331     m_profileModel->cloneProfile(idx);
0332 }
0333 
0334 bool SelectConnProfileController::validCharacter() const
0335 {
0336     return currentProfile() ?
0337                helper::utils::hasValidCharacter(currentProfile()->characters(), currentProfile()->isGM()) :
0338                false;
0339 }
0340 bool SelectConnProfileController::validCharacterName() const
0341 {
0342     if(!currentProfile())
0343         return false;
0344     auto characters= currentProfile()->characters();
0345     return std::any_of(std::begin(characters), std::end(characters),
0346                        [](const connection::CharacterData& data) { return !data.m_name.isEmpty(); });
0347 }
0348 bool SelectConnProfileController::validCharacterAvatar() const
0349 {
0350     if(!currentProfile())
0351         return false;
0352     auto characters= currentProfile()->characters();
0353     return std::any_of(std::begin(characters), std::end(characters),
0354                        [](const connection::CharacterData& data)
0355                        { return helper::utils::isSquareImage(data.m_avatarData); });
0356 }
0357 bool SelectConnProfileController::validCharacterColor() const
0358 {
0359     if(!currentProfile())
0360         return false;
0361     auto characters= currentProfile()->characters();
0362     return std::all_of(std::begin(characters), std::end(characters),
0363                        [](const connection::CharacterData& data) { return data.m_color.isValid(); });
0364 }
0365 
0366 const QString& SelectConnProfileController::infoMsg() const
0367 {
0368     return m_infoMsg;
0369 }
0370 
0371 void SelectConnProfileController::setInfoMsg(const QString& newInfoMsg)
0372 {
0373     if(m_infoMsg == newInfoMsg)
0374         return;
0375     m_infoMsg= newInfoMsg;
0376     emit infoMsgChanged();
0377 }
0378 
0379 const QByteArray SelectConnProfileController::password() const
0380 {
0381     return currentProfile() ? currentProfile()->password() : QByteArray();
0382 }
0383 
0384 void SelectConnProfileController::setPassword(const QByteArray& newPassword)
0385 {
0386     if(!currentProfile())
0387         return;
0388 
0389     currentProfile()->editPassword(newPassword);
0390 }
0391 void SelectConnProfileController::selectPlayerAvatar()
0392 {
0393     emit changePlayerAvatar();
0394 }
0395 void SelectConnProfileController::selectCampaignPath()
0396 {
0397     emit changeCampaignPath();
0398 }
0399 
0400 void SelectConnProfileController::selectCharacterAvatar(int i)
0401 {
0402     emit changeCharacterAvatar(i);
0403 }
0404 
0405 void SelectConnProfileController::startConnection()
0406 {
0407     setConnectionState(SelectConnProfileController::ConnectionState::LOADING);
0408     emit connectionStarted();
0409 }
0410 
0411 void SelectConnProfileController::reject()
0412 {
0413     emit rejected();
0414 }
0415 
0416 void SelectConnProfileController::saveProfileModels()
0417 {
0418     emit saveModels();
0419 }