File indexing completed on 2024-05-05 05:40:30
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/participantmodel.h" 0021 0022 #include <QDebug> 0023 #include <QFont> 0024 #include <QJsonArray> 0025 #include <QJsonObject> 0026 0027 #include "data/person.h" 0028 #include "data/player.h" 0029 #include "model/playermodel.h" 0030 0031 Player* findPlayer(const QString& id, PlayerModel* model) 0032 { 0033 if(model == nullptr) 0034 return nullptr; 0035 0036 return model->playerById(id); 0037 } 0038 0039 ParticipantItem* findItem(const QString& id, ParticipantItem* root) 0040 { 0041 ParticipantItem* wantedItem= nullptr; 0042 for(int i= 0; i < root->childCount(); ++i) 0043 { 0044 auto item= root->childAt(i); 0045 for(int j= 0; j < item->childCount(); ++j) 0046 { 0047 auto child= item->childAt(j); 0048 if(nullptr == child) 0049 continue; 0050 if(child->player()->uuid() == id) 0051 { 0052 wantedItem= child; 0053 } 0054 } 0055 } 0056 return wantedItem; 0057 } 0058 ParticipantItem::ParticipantItem(const QString& name) : m_name(name) {} 0059 0060 ParticipantItem::ParticipantItem(Player* player) : m_player(player) {} 0061 0062 bool ParticipantItem::isLeaf() const 0063 { 0064 return (m_player != nullptr); 0065 } 0066 0067 QString ParticipantItem::name() const 0068 { 0069 return isLeaf() ? m_player->name() : m_name; 0070 } 0071 0072 QString ParticipantItem::uuid() const 0073 { 0074 return isLeaf() ? m_player->uuid() : QString(); 0075 } 0076 0077 Player* ParticipantItem::player() const 0078 { 0079 return m_player; 0080 } 0081 0082 int ParticipantItem::indexOf(ParticipantItem* child) 0083 { 0084 return m_children.indexOf(child); 0085 } 0086 0087 int ParticipantItem::childCount() const 0088 { 0089 return m_children.size(); 0090 } 0091 0092 ParticipantItem* ParticipantItem::childAt(int pos) 0093 { 0094 if(qBound(0, pos, m_children.size() - 1) != pos) 0095 return nullptr; 0096 return m_children.at(pos); 0097 } 0098 0099 void ParticipantItem::appendChild(ParticipantItem* item) 0100 { 0101 m_children.append(item); 0102 item->setParent(this); 0103 } 0104 0105 void ParticipantItem::removeChild(ParticipantItem* item) 0106 { 0107 m_children.removeOne(item); 0108 } 0109 0110 ParticipantItem* ParticipantItem::parent() const 0111 { 0112 return m_parent; 0113 } 0114 0115 void ParticipantItem::setParent(ParticipantItem* parent) 0116 { 0117 m_parent= parent; 0118 } 0119 0120 ParticipantModel::ParticipantModel(const QString& ownerId, PlayerModel* model, QObject* parent) 0121 : QAbstractItemModel(parent), m_playerList(model), m_root(new ParticipantItem(QString())), m_ownerId(ownerId) 0122 { 0123 connect(model, &PlayerModel::playerJoin, this, &ParticipantModel::addNewPlayer); 0124 connect(model, &PlayerModel::playerLeft, this, &ParticipantModel::removePlayer); 0125 0126 m_root->appendChild(new ParticipantItem(tr("Read Write"))); 0127 m_root->appendChild(new ParticipantItem(tr("Read Only"))); 0128 m_root->appendChild(new ParticipantItem(tr("Hidden"))); 0129 0130 initModel(); 0131 } 0132 0133 QVariant ParticipantModel::headerData(int section, Qt::Orientation orientation, int role) const 0134 { 0135 return QVariant(); 0136 } 0137 0138 void ParticipantModel::initModel() 0139 { 0140 if(m_ownerId.isEmpty()) 0141 return; 0142 0143 beginResetModel(); 0144 auto c= m_playerList->rowCount(); 0145 for(int i= 0; i < c; ++i) 0146 { 0147 auto idx= m_playerList->index(i, 0, QModelIndex()); 0148 auto uuid= idx.data(PlayerModel::IdentifierRole).toString(); 0149 auto player= dynamic_cast<Player*>(idx.data(PlayerModel::PersonPtrRole).value<Person*>()); 0150 0151 auto dest= m_root->childAt(hidden); 0152 if(uuid == m_ownerId) 0153 dest= m_root->childAt(readWrite); 0154 0155 dest->appendChild(new ParticipantItem(player)); 0156 } 0157 endResetModel(); 0158 } 0159 0160 QModelIndex ParticipantModel::index(int row, int column, const QModelIndex& parent) const 0161 { 0162 if(!parent.isValid()) 0163 { 0164 auto p= m_root->childAt(row); 0165 return createIndex(row, column, p); 0166 } 0167 else 0168 { 0169 0170 auto p= m_root->childAt(parent.row()); 0171 auto data= p->childAt(row); 0172 return createIndex(row, column, data); 0173 } 0174 } 0175 0176 QModelIndex ParticipantModel::parent(const QModelIndex& index) const 0177 { 0178 if(!index.isValid()) 0179 return QModelIndex(); 0180 0181 auto item= static_cast<ParticipantItem*>(index.internalPointer()); 0182 0183 if(item == nullptr) 0184 return {}; 0185 0186 if(!item->isLeaf()) 0187 return QModelIndex(); 0188 0189 auto parentItem= item->parent(); 0190 0191 if(parentItem == nullptr) 0192 return {}; 0193 0194 return createIndex(m_root->indexOf(parentItem), 0, parentItem); 0195 } 0196 0197 int ParticipantModel::rowCount(const QModelIndex& parent) const 0198 { 0199 if(!parent.isValid()) 0200 return m_root->childCount(); 0201 0202 auto item= static_cast<ParticipantItem*>(parent.internalPointer()); 0203 0204 if(item->isLeaf()) 0205 return 0; 0206 0207 return item->childCount(); 0208 } 0209 0210 int ParticipantModel::columnCount(const QModelIndex& parent) const 0211 { 0212 return 1; 0213 } 0214 0215 QVariant ParticipantModel::data(const QModelIndex& index, int role) const 0216 { 0217 if(!index.isValid()) 0218 return QVariant(); 0219 0220 if(role != Qt::DisplayRole && role != Qt::EditRole && role != Qt::FontRole) 0221 return {}; 0222 0223 auto item= static_cast<ParticipantItem*>(index.internalPointer()); 0224 0225 if(item->uuid() == m_ownerId && role == Qt::FontRole) 0226 { 0227 QFont font; 0228 font.setBold(true); 0229 return font; 0230 } 0231 else if(role == Qt::FontRole) 0232 return {}; 0233 0234 return item->name(); 0235 } 0236 0237 Qt::ItemFlags ParticipantModel::flags(const QModelIndex& index) const 0238 { 0239 if(!index.isValid()) 0240 return Qt::NoItemFlags; 0241 if(index.parent().isValid()) 0242 return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDropEnabled; 0243 else 0244 return Qt::ItemIsEnabled | Qt::ItemIsSelectable; 0245 } 0246 0247 void ParticipantModel::addNewPlayer(Player* player) 0248 { 0249 if(nullptr == player) 0250 return; 0251 0252 auto catInt= hidden; 0253 if(player->uuid() == m_ownerId) 0254 catInt= readWrite; 0255 auto permData= m_root->childAt(catInt); 0256 auto parent= createIndex(static_cast<int>(catInt), 0, permData); 0257 beginInsertRows(parent, permData->childCount(), permData->childCount()); 0258 permData->appendChild(new ParticipantItem(player)); 0259 endInsertRows(); 0260 } 0261 0262 void ParticipantModel::removePlayer(Player* player) 0263 { 0264 if(nullptr == player) 0265 return; 0266 0267 ParticipantItem* origin= nullptr; 0268 ParticipantItem* parent= nullptr; 0269 for(int i= 0; i < m_root->childCount(); ++i) 0270 { 0271 auto item= m_root->childAt(i); 0272 for(int j= 0; j < item->childCount(); ++j) 0273 { 0274 auto child= item->childAt(j); 0275 if(child->player() == player) 0276 { 0277 origin= child; 0278 parent= item; 0279 } 0280 } 0281 } 0282 0283 if(origin == nullptr || parent == nullptr) 0284 return; 0285 0286 auto pos= parent->indexOf(origin); 0287 auto parentIdx= createIndex(m_root->indexOf(parent), 0, parent); 0288 beginRemoveRows(parentIdx, pos, pos); 0289 parent->removeChild(origin); 0290 endRemoveRows(); 0291 } 0292 0293 int ParticipantModel::promotePlayer(const QModelIndex& index) 0294 { 0295 ParticipantModel::Permission perm= permissionFor(index); 0296 switch(perm) 0297 { 0298 case readOnly: 0299 case hidden: 0300 setPlayerInto(index, static_cast<Permission>(perm - 1)); 0301 return static_cast<Permission>(perm - 1); 0302 default: 0303 break; 0304 } 0305 return -1; 0306 } 0307 0308 int ParticipantModel::demotePlayer(const QModelIndex& index) 0309 { 0310 if(!index.isValid()) 0311 return 0; 0312 0313 ParticipantModel::Permission perm= permissionFor(index); 0314 switch(perm) 0315 { 0316 case readOnly: 0317 case readWrite: 0318 setPlayerInto(index, static_cast<Permission>(perm + 1)); 0319 return static_cast<Permission>(perm + 1); 0320 default: 0321 break; 0322 } 0323 return -1; 0324 } 0325 QString ParticipantModel::getOwner() const 0326 { 0327 return m_ownerId; 0328 } 0329 0330 void ParticipantModel::setOwner(const QString& owner) 0331 { 0332 if(owner == m_ownerId) 0333 return; 0334 m_ownerId= owner; 0335 initModel(); 0336 } 0337 ParticipantModel::Permission ParticipantModel::permissionFor(const QModelIndex& index) 0338 { 0339 if(!index.isValid()) 0340 return hidden; 0341 0342 auto parent= index.parent(); 0343 if(!parent.isValid()) 0344 return hidden; 0345 0346 return static_cast<Permission>(parent.row()); 0347 } 0348 0349 ParticipantModel::Permission ParticipantModel::permissionFor(const QString& id) 0350 { 0351 auto item= findItem(id, m_root.get()); 0352 if(!item) 0353 return hidden; 0354 auto parent= item->parent(); 0355 auto val= m_root->indexOf(parent); 0356 0357 if(val < 0) 0358 return hidden; 0359 0360 return static_cast<ParticipantModel::Permission>(val); 0361 } 0362 0363 void ParticipantModel::setPlayerInto(const QModelIndex& index, Permission level) 0364 { 0365 QModelIndex parent= index.parent(); 0366 if(!parent.isValid()) 0367 return; 0368 0369 auto item= static_cast<ParticipantItem*>(index.internalPointer()); 0370 if(item == nullptr) 0371 return; 0372 0373 QModelIndex destParent= createIndex(static_cast<int>(level), 0, m_root.get()); 0374 0375 auto r= rowCount(destParent); 0376 auto perm= m_root->childAt(level); 0377 auto permSource= static_cast<ParticipantItem*>(parent.internalPointer()); 0378 0379 QString id; 0380 auto p= item->player(); 0381 if(nullptr != p) 0382 id= p->uuid(); 0383 0384 if(id == m_ownerId) 0385 return; 0386 0387 beginMoveRows(parent, index.row(), index.row(), destParent, r); 0388 permSource->removeChild(item); 0389 perm->appendChild(item); 0390 endMoveRows(); 0391 0392 auto hideRoot= m_root->childAt(hidden); 0393 auto roRoot= m_root->childAt(readOnly); 0394 auto rwRoot= m_root->childAt(readWrite); 0395 0396 if(permSource == hideRoot && perm == roRoot) 0397 emit userReadPermissionChanged(id, true); 0398 else if(permSource == roRoot && perm == hideRoot) 0399 emit userReadPermissionChanged(id, false); 0400 0401 if(permSource == roRoot && perm == rwRoot) 0402 emit userWritePermissionChanged(id, true); 0403 else if(permSource == rwRoot && perm == roRoot) 0404 emit userWritePermissionChanged(id, false); 0405 } 0406 0407 void ParticipantModel::setPlayerPermission(const QString& id, ParticipantModel::Permission level) 0408 { 0409 auto item= findItem(id, m_root.get()); 0410 if(!item) 0411 return; 0412 auto parent= item->parent(); 0413 auto parentIdx= index(m_root->indexOf(parent), 0, QModelIndex()); 0414 auto itemIdx= index(parent->indexOf(item), 0, parentIdx); 0415 setPlayerInto(itemIdx, level); 0416 } 0417 0418 void ParticipantModel::saveModel(QJsonObject& root) 0419 { 0420 0421 QJsonArray array; 0422 for(int i= 0; i < m_root->childCount(); ++i) 0423 { 0424 auto child= m_root->childAt(i); 0425 auto perm= readWrite; 0426 if(i == 1) 0427 perm= readOnly; 0428 else if(i == 2) 0429 perm= hidden; 0430 0431 for(int j= 0; j < child->childCount(); ++j) 0432 { 0433 auto leaf= child->childAt(j); 0434 QJsonObject obj; 0435 obj["id"]= leaf->uuid(); 0436 obj["perm"]= perm; 0437 array.append(obj); 0438 } 0439 } 0440 root["data"]= array; 0441 } 0442 void ParticipantModel::loadModel(QJsonObject& root) 0443 { 0444 /*PlayerModel* playerList= PlayerModel::instance(); 0445 0446 QJsonArray hidden= root["hidden"].toArray(); 0447 QJsonArray readOnly= root["readOnly"].toArray(); 0448 QJsonArray readWrite= root["readWrite"].toArray(); 0449 0450 beginResetModel(); 0451 0452 m_hidden.clear(); 0453 m_readOnly.clear(); 0454 m_readWrite.clear(); 0455 0456 for(auto playerId : hidden) 0457 { 0458 Player* p= dynamic_cast<Player*>(playerList->getPerson(playerId.toString())); 0459 m_hidden.append(p); 0460 } 0461 0462 for(auto playerId : readOnly) 0463 { 0464 Player* p= dynamic_cast<Player*>(playerList->getPerson(playerId.toString())); 0465 m_readOnly.append(p); 0466 } 0467 0468 for(auto playerId : readWrite) 0469 { 0470 Player* p= dynamic_cast<Player*>(playerList->getPerson(playerId.toString())); 0471 m_readWrite.append(p); 0472 } 0473 endResetModel();*/ 0474 }