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 }