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/participantsmodel.h"
0021 
0022 #include "data/player.h"
0023 #include "model/playermodel.h"
0024 #include <QJsonArray>
0025 
0026 ParticipantsModel::Permission permissionFor(const QModelIndex& index)
0027 {
0028     return static_cast<ParticipantsModel::Permission>(index.parent().row());
0029 }
0030 
0031 ParticipantsModel::ParticipantsModel()
0032 {
0033     m_permissionGroup << tr("Read Write") << tr("Read Only") << tr("Hidden");
0034 }
0035 
0036 int ParticipantsModel::rowCount(const QModelIndex& parent) const
0037 {
0038     if(!parent.isValid())
0039         return Permission_count;
0040 
0041     if(parent.row() == ReadWrite)
0042         return m_readWrite.size();
0043 
0044     if(parent.row() == ReadOnly)
0045         return m_readOnly.size();
0046 
0047     auto total= sourceModel()->rowCount(QModelIndex());
0048     return total - (m_readOnly.size() + m_readWrite.size());
0049 }
0050 
0051 int ParticipantsModel::columnCount(const QModelIndex& parent) const
0052 {
0053     if(parent.isValid())
0054         return 0;
0055     return 1;
0056 }
0057 
0058 QVariant ParticipantsModel::data(const QModelIndex& index, int role) const
0059 {
0060     static QSet<int> set{PlayerModel::IdentifierRole, Qt::DisplayRole};
0061     if(!index.isValid() || !set.contains(role))
0062         return QVariant();
0063 
0064     QModelIndex parent= index.parent();
0065     if(!parent.isValid())
0066         return m_permissionGroup.at(index.row());
0067 
0068     auto mapIndex= mapToSource(index);
0069 
0070     if(index.isValid())
0071         return mapIndex.data(role);
0072 
0073     return {};
0074 }
0075 
0076 QModelIndex ParticipantsModel::parent(const QModelIndex& child) const
0077 {
0078     if(!child.isValid())
0079         return QModelIndex();
0080 
0081     Player* childItem= static_cast<Player*>(child.internalPointer());
0082 
0083     if(nullptr == childItem)
0084         return QModelIndex();
0085 
0086     auto uuid= childItem->uuid();
0087     if(m_readWrite.contains(uuid))
0088         return createIndex(ReadWrite, 0, nullptr);
0089 
0090     if(m_readOnly.contains(uuid))
0091         return createIndex(ReadOnly, 0, nullptr);
0092 
0093     return createIndex(Hidden, 0, nullptr);
0094 }
0095 
0096 QModelIndex ParticipantsModel::index(int row, int column, const QModelIndex& parent) const
0097 {
0098     if(row < 0)
0099         return QModelIndex();
0100 
0101     if(!parent.isValid())
0102         return createIndex(row, column, nullptr); // internalPointer is null for category
0103 
0104     auto cat= parent.row();
0105     QString uuid;
0106     if(cat == ReadWrite && row < m_readWrite.size())
0107         uuid= m_readWrite[row];
0108 
0109     if(cat == ReadOnly && row < m_readOnly.size())
0110         uuid= m_readOnly[row];
0111 
0112     Player* player= nullptr;
0113     if(uuid.isNull())
0114     {
0115         auto tmpRow= row;
0116         for(int i= 0; i < sourceModel()->rowCount() && tmpRow >= 0; ++i)
0117         {
0118             auto idx= sourceModel()->index(i, 0);
0119             auto person= idx.data(PlayerModel::PersonPtrRole).value<Person*>();
0120 
0121             auto uuid= person->uuid();
0122 
0123             if(m_readWrite.contains(uuid) || m_readOnly.contains(uuid))
0124                 continue;
0125 
0126             if(tmpRow == 0)
0127             {
0128                 player= dynamic_cast<Player*>(person);
0129             }
0130             --tmpRow;
0131         }
0132     }
0133     else
0134     {
0135         for(int i= 0; i < sourceModel()->rowCount() && player == nullptr; ++i)
0136         {
0137             auto idx= sourceModel()->index(i, 0);
0138             auto person= idx.data(PlayerModel::PersonPtrRole).value<Person*>();
0139 
0140             if(person->uuid() == uuid)
0141                 player= dynamic_cast<Player*>(person);
0142         }
0143     }
0144 
0145     if(nullptr != player)
0146         return createIndex(row, column, player);
0147 
0148     return {};
0149 }
0150 
0151 Qt::ItemFlags ParticipantsModel::flags(const QModelIndex& index) const
0152 {
0153     if(!index.isValid())
0154         return Qt::NoItemFlags;
0155 
0156     return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDropEnabled;
0157 }
0158 
0159 QModelIndex ParticipantsModel::mapFromSource(const QModelIndex& sourceIndex) const
0160 {
0161     if(!sourceIndex.isValid())
0162         return QModelIndex();
0163 
0164     auto parent= sourceIndex.parent();
0165 
0166     if(parent.isValid())
0167         return QModelIndex();
0168 
0169     auto p= static_cast<Person*>(sourceIndex.internalPointer());
0170     auto id= p->uuid();
0171 
0172     auto row= m_readWrite.indexOf(id);
0173     if(row < 0)
0174         row= m_readOnly.indexOf(id);
0175 
0176     if(row < 0)
0177     {
0178         QStringList listId;
0179         for(int i= 0; i < sourceIndex.row(); ++i)
0180         {
0181             auto idx= sourceModel()->index(i, 0, QModelIndex());
0182             listId << idx.data(PlayerModel::IdentifierRole).toString();
0183         }
0184     }
0185 
0186     return createIndex(sourceIndex.row(), 0, sourceIndex.internalPointer());
0187 }
0188 
0189 QModelIndex ParticipantsModel::mapToSource(const QModelIndex& proxyIndex) const
0190 {
0191     return sourceModel()->index(proxyIndex.row(), 0, QModelIndex());
0192 }
0193 
0194 QString ParticipantsModel::ownerId() const
0195 {
0196     return m_ownerId;
0197 }
0198 
0199 void ParticipantsModel::setOwnerId(const QString& id)
0200 {
0201     m_ownerId= id;
0202 }
0203 
0204 void ParticipantsModel::saveModel(QJsonObject& root)
0205 {
0206     QJsonArray readOnly;
0207     QJsonArray readWrite;
0208 
0209     for(auto& id : m_readOnly)
0210     {
0211         readOnly << id;
0212     }
0213 
0214     for(auto& id : m_readWrite)
0215     {
0216         readWrite << id;
0217     }
0218 
0219     root["readOnly"]= readOnly;
0220     root["readWrite"]= readWrite;
0221 }
0222 void ParticipantsModel::loadModel(QJsonObject& root)
0223 {
0224     QJsonArray readOnly= root["readOnly"].toArray();
0225     QJsonArray readWrite= root["readWrite"].toArray();
0226 
0227     beginResetModel();
0228 
0229     m_readOnly.clear();
0230     m_readWrite.clear();
0231 
0232     for(auto playerId : readOnly)
0233     {
0234         m_readOnly.append(playerId.toString());
0235     }
0236 
0237     for(auto playerId : readWrite)
0238     {
0239         m_readWrite.append(playerId.toString());
0240     }
0241     endResetModel();
0242 }
0243 
0244 ParticipantsModel::Permission ParticipantsModel::getPermissionFor(Player* player)
0245 {
0246     if(!player)
0247         return ParticipantsModel::Hidden;
0248 
0249     auto id= player->uuid();
0250 
0251     if(m_readOnly.contains(id))
0252         return ParticipantsModel::ReadOnly;
0253 
0254     else if(m_readWrite.contains(id))
0255         return ParticipantsModel::ReadWrite;
0256 
0257     return ParticipantsModel::Hidden;
0258 }
0259 
0260 void ParticipantsModel::promotePlayer(const QModelIndex& index)
0261 {
0262     ParticipantsModel::Permission perm= permissionFor(index);
0263     switch(perm)
0264     {
0265     case ReadOnly:
0266         promotePlayerToReadWrite(index);
0267         break;
0268     case Hidden:
0269         promotePlayerToRead(index);
0270         break;
0271     default:
0272         break;
0273     }
0274 }
0275 
0276 void ParticipantsModel::demotePlayer(const QModelIndex& index)
0277 {
0278     ParticipantsModel::Permission perm= permissionFor(index);
0279     switch(perm)
0280     {
0281     case ParticipantsModel::ReadOnly:
0282         demotePlayerToHidden(index);
0283         break;
0284     case ParticipantsModel::ReadWrite:
0285         demotePlayerToRead(index);
0286         break;
0287     default:
0288         break;
0289     }
0290 }
0291 
0292 void ParticipantsModel::promotePlayerToRead(const QModelIndex& index)
0293 {
0294     auto uuid= data(index, PlayerModel::IdentifierRole).toString();
0295     if(uuid.isEmpty())
0296         return;
0297 
0298     beginResetModel();
0299     m_readOnly.append(uuid);
0300     endResetModel();
0301 }
0302 
0303 void ParticipantsModel::promotePlayerToReadWrite(const QModelIndex& index)
0304 {
0305     auto uuid= data(index, PlayerModel::IdentifierRole).toString();
0306     if(uuid.isEmpty())
0307         return;
0308     auto parent= createIndex(1, 0);
0309     beginRemoveRows(parent, m_readOnly.indexOf(uuid), m_readOnly.indexOf(uuid));
0310     auto b= m_readOnly.removeOne(uuid);
0311     Q_ASSERT(b);
0312     endRemoveRows();
0313 
0314     parent= createIndex(0, 0);
0315     beginInsertRows(parent, m_readWrite.size(), m_readWrite.size());
0316     m_readWrite.append(uuid);
0317     endInsertRows();
0318 }
0319 
0320 void ParticipantsModel::demotePlayerToRead(const QModelIndex& index)
0321 {
0322     auto uuid= data(index, PlayerModel::IdentifierRole).toString();
0323     if(uuid.isEmpty())
0324         return;
0325     auto parent= createIndex(0, 0);
0326     beginRemoveRows(parent, m_readWrite.indexOf(uuid), m_readWrite.indexOf(uuid));
0327     auto b= m_readWrite.removeOne(uuid);
0328     Q_ASSERT(b);
0329     endRemoveRows();
0330 
0331     parent= createIndex(1, 0);
0332     beginInsertRows(parent, m_readOnly.size(), m_readOnly.size());
0333     m_readOnly.append(uuid);
0334     endInsertRows();
0335 }
0336 
0337 void ParticipantsModel::demotePlayerToHidden(const QModelIndex& index)
0338 {
0339     auto uuid= data(index, PlayerModel::IdentifierRole).toString();
0340     if(uuid.isEmpty())
0341         return;
0342     beginResetModel();
0343     auto b= m_readOnly.removeOne(uuid);
0344     Q_ASSERT(b);
0345     endResetModel();
0346 }