File indexing completed on 2024-05-05 05:40:27
0001 /*************************************************************************** 0002 * Copyright (C) 2009 by Renaud Guezennec * 0003 * https://rolisteam.org/contact * 0004 * * 0005 * Rolisteam 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/characterstatemodel.h" 0021 0022 #include <QBuffer> 0023 #include <QColor> 0024 #include <QJsonArray> 0025 #include <QJsonObject> 0026 #include <algorithm> 0027 0028 CharacterStateModel::CharacterStateModel(QObject* parent) : QAbstractListModel(parent) 0029 { 0030 m_header << tr("Label") << tr("Color") << tr("Image"); 0031 } 0032 0033 CharacterStateModel::~CharacterStateModel() {} 0034 0035 int CharacterStateModel::columnCount(const QModelIndex&) const 0036 { 0037 return m_header.size(); 0038 } 0039 QVariant CharacterStateModel::data(const QModelIndex& index, int role) const 0040 { 0041 if(!index.isValid()) 0042 return {}; 0043 QSet<int> allowedRole{Qt::EditRole, Qt::DisplayRole, Qt::BackgroundRole, LABEL, COLOR, PICTUREPATH, PICTURE, ID}; 0044 0045 if(!allowedRole.contains(role)) 0046 return {}; 0047 0048 QVariant var; 0049 auto const& state= m_stateList[static_cast<std::size_t>(index.row())]; 0050 auto c= index.column(); 0051 0052 int realRole= role; 0053 if(role < LABEL) 0054 realRole= LABEL + c; 0055 0056 switch(realRole) 0057 { 0058 case LABEL: 0059 var= state->label(); 0060 break; 0061 case ID: 0062 var= state->id(); 0063 break; 0064 case COLOR: 0065 var= state->color(); 0066 break; 0067 case PICTURE: 0068 { 0069 QPixmap map(state->imagePath()); 0070 var= QVariant::fromValue(map); 0071 } 0072 break; 0073 case PICTUREPATH: 0074 var= state->imagePath(); 0075 break; 0076 } 0077 return var; 0078 } 0079 int CharacterStateModel::rowCount(const QModelIndex& parent) const 0080 { 0081 if(!parent.isValid()) 0082 return static_cast<int>(m_stateList.size()); 0083 return 0; 0084 } 0085 0086 QVariant CharacterStateModel::headerData(int section, Qt::Orientation orientation, int role) const 0087 { 0088 if(Qt::DisplayRole == role) 0089 { 0090 if(orientation == Qt::Horizontal) 0091 { 0092 return m_header.at(section); 0093 } 0094 } 0095 return QVariant(); 0096 } 0097 int CharacterStateModel::indexFromId(const QString& id) const 0098 { 0099 auto it= std::find_if(std::begin(m_stateList), std::end(m_stateList), 0100 [id](const std::unique_ptr<CharacterState>& state) { return id == state->id(); }); 0101 0102 if(it == std::end(m_stateList)) 0103 return -1; 0104 0105 return std::distance(std::begin(m_stateList), it); 0106 } 0107 /*void CharacterStateModel::setStates(QList<CharacterState*>* lst) 0108 { 0109 beginResetModel(); 0110 std::transform(lst->begin(), lst->end(), std::back_inserter(m_stateList), 0111 [](CharacterState* state) -> CharacterStateInfo { 0112 CharacterStateInfo a= makeStateInfo(state, false); 0113 // TODO c++14 list initializer 0114 return a; 0115 }); 0116 endResetModel(); 0117 }*/ 0118 0119 /*void CharacterStateModel::preferencesHasChanged(const QString& pref) 0120 { 0121 if(pref == "isPlayer") 0122 { 0123 // m_isGM= !PreferencesManager::getInstance()->value(pref, true).toBool(); 0124 } 0125 }*/ 0126 /*NetWorkReceiver::SendType CharacterStateModel::processMessage(NetworkMessageReader* msg) 0127 { 0128 NetWorkReceiver::SendType type= NetWorkReceiver::AllExceptSender; 0129 0130 if(nullptr == msg) 0131 return NetWorkReceiver::NONE; 0132 0133 switch(msg->action()) 0134 { 0135 case NetMsg::addCharacterState: 0136 processAddState(msg); 0137 break; 0138 case NetMsg::removeCharacterState: 0139 processRemoveState(msg); 0140 break; 0141 case NetMsg::moveCharacterState: 0142 processMoveState(msg); 0143 break; 0144 case NetMsg::CharactereStateModel: 0145 processModelState(msg); 0146 break; 0147 default: 0148 break; 0149 } 0150 0151 return type; 0152 } 0153 */ 0154 0155 void CharacterStateModel::appendState(CharacterState&& stateRef) 0156 { 0157 auto isInside= std::find_if(std::begin(m_stateList), std::end(m_stateList), 0158 [stateRef](const std::unique_ptr<CharacterState>& state) 0159 { return state->id() == stateRef.id(); }); 0160 0161 if(isInside != std::end(m_stateList)) 0162 return; 0163 0164 auto pos= static_cast<int>(m_stateList.size()); 0165 beginInsertRows(QModelIndex(), pos, pos); 0166 m_stateList.push_back(std::make_unique<CharacterState>(stateRef)); 0167 endInsertRows(); 0168 auto const& it= m_stateList.end() - 1; 0169 emit characterStateAdded((*it).get(), pos); 0170 } 0171 Qt::ItemFlags CharacterStateModel::flags(const QModelIndex& index) const 0172 { 0173 if(!index.isValid()) 0174 return Qt::NoItemFlags; 0175 return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsDragEnabled; 0176 } 0177 bool CharacterStateModel::setData(const QModelIndex& idx, const QVariant& value, int role) 0178 { 0179 bool result= false; 0180 if(!idx.isValid()) 0181 return result; 0182 0183 auto const& state= m_stateList[idx.row()]; 0184 if(role != Qt::EditRole) 0185 return result; 0186 0187 QVector<int> roles{LABEL, COLOR, PICTUREPATH, PICTURE, ID}; 0188 0189 switch(roles[idx.column()]) 0190 { 0191 case LABEL: 0192 state->setLabel(value.toString()); 0193 result= true; 0194 break; 0195 case COLOR: 0196 state->setColor(value.value<QColor>()); 0197 result= true; 0198 break; 0199 case PICTUREPATH: 0200 state->setImagePath(value.toString()); 0201 result= true; 0202 break; 0203 } 0204 0205 emit dataChanged(index(idx.row(), 0), index(idx.row(), columnCount()), 0206 QVector<int>() << role << roles[idx.column()]); 0207 emit stateChanged(); 0208 return result; 0209 } 0210 0211 const std::vector<std::unique_ptr<CharacterState>>& CharacterStateModel::statesList() const 0212 { 0213 return m_stateList; 0214 } 0215 void CharacterStateModel::deleteState(const QModelIndex& index) 0216 { 0217 if(!index.isValid()) 0218 return; 0219 beginRemoveRows(QModelIndex(), index.row(), index.row()); 0220 auto const& it= m_stateList.begin() + index.row(); 0221 auto id= (*it)->id(); 0222 m_stateList.erase(it); 0223 endRemoveRows(); 0224 0225 emit stateRemoved(id); 0226 } 0227 void CharacterStateModel::upState(const QModelIndex& index) 0228 { 0229 if(!index.isValid()) 0230 return; 0231 if(index.row() == 0) 0232 return; 0233 if(beginMoveRows(QModelIndex(), index.row(), index.row(), QModelIndex(), index.row() - 1)) 0234 { 0235 std::iter_swap(m_stateList.begin() + index.row(), m_stateList.begin() + index.row() - 1); 0236 endMoveRows(); 0237 emit stateMoved(index.row(), index.row() - 1); 0238 } 0239 } 0240 0241 void CharacterStateModel::downState(const QModelIndex& index) 0242 { 0243 if(!index.isValid()) 0244 return; 0245 0246 if(index.row() == static_cast<int>(m_stateList.size()) - 1) 0247 return; 0248 0249 if(beginMoveRows(QModelIndex(), index.row(), index.row(), QModelIndex(), index.row() + 2)) 0250 { 0251 std::iter_swap(m_stateList.begin() + index.row(), m_stateList.begin() + index.row() + 1); 0252 endMoveRows(); 0253 emit stateMoved(index.row(), index.row() + 1); 0254 } 0255 } 0256 0257 void CharacterStateModel::topState(const QModelIndex& index) 0258 { 0259 if(!index.isValid()) 0260 return; 0261 0262 if(index.row() == 0) 0263 return; 0264 if(beginMoveRows(QModelIndex(), index.row(), index.row(), QModelIndex(), 0)) 0265 { 0266 std::iter_swap(m_stateList.begin(), m_stateList.begin() + index.row()); 0267 endMoveRows(); 0268 emit stateMoved(index.row(), 0); 0269 } 0270 } 0271 0272 void CharacterStateModel::bottomState(const QModelIndex& index) 0273 { 0274 if(!index.isValid()) 0275 return; 0276 auto size= static_cast<int>(m_stateList.size()); 0277 if(index.row() == size - 1) 0278 return; 0279 if(beginMoveRows(QModelIndex(), index.row(), index.row(), QModelIndex(), size)) 0280 { 0281 std::iter_swap(m_stateList.end() - 1, m_stateList.begin() + index.row()); 0282 endMoveRows(); 0283 emit stateMoved(index.row(), size); 0284 } 0285 } 0286 0287 void CharacterStateModel::moveState(int from, int to) 0288 { 0289 if((from >= 0) && (from < static_cast<int>(m_stateList.size()))) 0290 { 0291 beginMoveRows(QModelIndex(), from, from, QModelIndex(), to); 0292 std::iter_swap(m_stateList.begin() + to, m_stateList.begin() + from); 0293 endMoveRows(); 0294 } 0295 } 0296 0297 void CharacterStateModel::removeStateAt(int i) 0298 { 0299 deleteState(index(i, 0)); 0300 } 0301 0302 QString CharacterStateModel::stateLabelFromId(const QString& id) 0303 { 0304 if(id.isEmpty()) 0305 return {}; 0306 0307 auto it= std::find_if(std::begin(m_stateList), std::end(m_stateList), 0308 [id](const std::unique_ptr<CharacterState>& state) { return state->id() == id; }); 0309 0310 if(it == std::end(m_stateList)) 0311 return {}; 0312 0313 return (*it)->label(); 0314 } 0315 0316 void CharacterStateModel::clear() 0317 { 0318 beginResetModel(); 0319 m_stateList.clear(); 0320 endResetModel(); 0321 } 0322 /* 0323 void CharacterStateModel::processAddState(NetworkMessageReader* msg) 0324 { 0325 CharacterState* state= new CharacterState(); 0326 0327 quint64 id= msg->uint64(); 0328 state->setLabel(msg->string32()); 0329 state->setColor(msg->rgb()); 0330 bool hasImage= static_cast<bool>(msg->uint8()); 0331 if(hasImage) 0332 { 0333 QByteArray array= msg->byteArray32(); 0334 QPixmap pix; 0335 pix.loadFromData(array); 0336 state->setImage(pix); 0337 } 0338 m_stateList.push_back(makeStateInfo(state, true)); 0339 } 0340 void CharacterStateModel::processMoveState(NetworkMessageReader* msg) 0341 { 0342 int from= msg->int64(); 0343 int to= msg->int64(); 0344 0345 if((from >= 0) && (from < m_stateList.size())) 0346 { 0347 beginMoveRows(QModelIndex(), from, from, QModelIndex(), to); 0348 std::iter_swap(m_stateList.begin() + to, m_stateList.begin() + from); 0349 endMoveRows(); 0350 } 0351 } 0352 void CharacterStateModel::processRemoveState(NetworkMessageReader* msg) 0353 { 0354 int pos= static_cast<int>(msg->int64()); 0355 if(m_stateList.size() < pos) 0356 return; 0357 0358 beginRemoveRows(QModelIndex(), pos, pos); 0359 m_stateList.erase(m_stateList.begin() + pos); 0360 endRemoveRows(); 0361 } 0362 0363 void CharacterStateModel::sendOffAllCharacterState() 0364 { 0365 for(auto& state : *m_stateList) 0366 { 0367 NetworkMessageWriter msg(NetMsg::SharePreferencesCategory, NetMsg::addState); 0368 msg.uint64(m_stateList->indexOf(state)); 0369 msg.string32(state->label()); 0370 msg.rgb(state->getColor().rgb()); 0371 if(state->hasImage()) 0372 { 0373 msg.uint8(static_cast<quint8>(true)); 0374 0375 QByteArray array; 0376 QBuffer buffer(&array); 0377 if(!state->getPixmap()->save(&buffer, "PNG")) 0378 { 0379 qWarning("error during encoding png"); 0380 } 0381 msg.byteArray32(array); 0382 } 0383 else 0384 { 0385 msg.uint8(static_cast<quint8>(false)); 0386 } 0387 msg.sendToServer(); 0388 } 0389 if(result) // isGM 0390 { 0391 NetworkMessageWriter msg(NetMsg::SharePreferencesCategory, NetMsg::addCharacterState); 0392 msg.int64(index.row()); 0393 msg.string32(stateInfo.state->label()); 0394 msg.rgb(stateInfo.state->getColor().rgb()); 0395 msg.uint8(stateInfo.state->hasImage()); 0396 if(stateInfo.state->hasImage()) 0397 { 0398 auto img= stateInfo.state->getImage(); 0399 QByteArray array; 0400 QBuffer buffer(&array); 0401 img.save(&buffer, "PNG"); 0402 msg.byteArray32(array); 0403 } 0404 msg.sendToServer(); 0405 } 0406 }*/ 0407 0408 // void CharacterStateModel::moveState(int from, int to) 0409 //{ 0410 // if(m_isGM) 0411 // { 0412 /* NetworkMessageWriter msg(NetMsg::SharePreferencesCategory, NetMsg::moveCharacterState); 0413 msg.int64(from); 0414 msg.int64(to); 0415 msg.sendToServer();*/ 0416 // } 0417 //}