File indexing completed on 2024-11-10 05:11:09
0001 /* 0002 * Copyright 2018 by Marco Martin <mart@kde.org> 0003 * 0004 * Licensed under the Apache License, Version 2.0 (the "License"); 0005 * you may not use this file except in compliance with the License. 0006 * You may obtain a copy of the License at 0007 * 0008 * http://www.apache.org/licenses/LICENSE-2.0 0009 * 0010 * Unless required by applicable law or agreed to in writing, software 0011 * distributed under the License is distributed on an "AS IS" BASIS, 0012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 0013 * See the License for the specific language governing permissions and 0014 * limitations under the License. 0015 * 0016 */ 0017 0018 #include "activeskillsmodel.h" 0019 #include "delegatesmodel.h" 0020 #include "abstractdelegate.h" 0021 0022 #include <QDebug> 0023 0024 0025 ActiveSkillsModel::ActiveSkillsModel(QObject *parent) 0026 : QAbstractListModel(parent) 0027 { 0028 } 0029 0030 ActiveSkillsModel::~ActiveSkillsModel() 0031 { 0032 //TODO: delete everything 0033 } 0034 0035 void ActiveSkillsModel::syncActiveIndex() 0036 { 0037 if (m_skills.isEmpty()) { 0038 m_activeIndex = -1; 0039 emit activeIndexChanged(); 0040 } 0041 0042 int index = -1; 0043 int i = 0; 0044 for (const auto &skill : m_skills) { 0045 0046 if (skillAllowed(skill)) { 0047 index = i; 0048 break; 0049 } 0050 ++i; 0051 } 0052 0053 if (m_activeIndex != index) { 0054 m_activeIndex = index; 0055 emit activeIndexChanged(); 0056 } 0057 } 0058 0059 int ActiveSkillsModel::activeIndex() const 0060 { 0061 return m_activeIndex; 0062 } 0063 0064 0065 QStringList ActiveSkillsModel::blackList() const 0066 { 0067 return m_blackList; 0068 } 0069 0070 void ActiveSkillsModel::setBlackList(const QStringList &list) 0071 { 0072 if (list == m_blackList) { 0073 return; 0074 } 0075 0076 m_blackList = list; 0077 0078 // TODO: delete/create delegates? 0079 emit blackListChanged(); 0080 } 0081 0082 QStringList ActiveSkillsModel::whiteList() const 0083 { 0084 return m_whiteList; 0085 } 0086 0087 void ActiveSkillsModel::setWhiteList(const QStringList &list) 0088 { 0089 if (list == m_whiteList) { 0090 return; 0091 } 0092 0093 m_whiteList = list; 0094 0095 emit whiteListChanged(); 0096 } 0097 0098 void ActiveSkillsModel::checkGuiActivation(const QString &skillId) 0099 { 0100 if (!skillAllowed(skillId)) { 0101 emit blacklistedSkillActivated(skillId); 0102 return; 0103 } 0104 0105 if (activeSkills().isEmpty()) { 0106 return; 0107 } 0108 0109 if (activeSkills().first() == skillId) { 0110 emit skillActivated(skillId); 0111 } 0112 } 0113 0114 bool ActiveSkillsModel::skillAllowed(const QString skillId) const 0115 { 0116 return !m_blackList.contains(skillId) && (m_whiteList.isEmpty() || m_whiteList.contains(skillId)); 0117 } 0118 0119 void ActiveSkillsModel::insertSkills(int position, const QStringList &skillList) 0120 { 0121 if (position < 0 || position > m_skills.count()) { 0122 return; 0123 } 0124 0125 QStringList filteredList; 0126 0127 std::copy_if(skillList.begin(), skillList.end(), 0128 std::back_inserter(filteredList), 0129 [this](const QString &val) 0130 { 0131 return !m_skills.contains(val); 0132 }); 0133 0134 if (filteredList.isEmpty()) { 0135 return; 0136 } 0137 0138 beginInsertRows(QModelIndex(), position, position + filteredList.count() - 1); 0139 0140 int i = 0; 0141 for (const auto &skillId : filteredList) { 0142 m_skills.insert(position + i, skillId); 0143 ++i; 0144 } 0145 //First syncactiveindex then endInserRows as it could make the view think we don't have any delegates for current skill 0146 syncActiveIndex(); 0147 endInsertRows(); 0148 0149 //TODO: activate proper skills 0150 if (position == m_activeIndex) { 0151 checkGuiActivation(filteredList.first()); 0152 } 0153 } 0154 0155 QStringList ActiveSkillsModel::activeSkills() const 0156 { 0157 return m_skills; 0158 } 0159 0160 QModelIndex ActiveSkillsModel::skillIndex(const QString &skillId) 0161 { 0162 const int row = m_skills.indexOf(skillId); 0163 0164 if (row >= 0) { 0165 return index(row, 0, QModelIndex()); 0166 } 0167 0168 return QModelIndex(); 0169 } 0170 0171 DelegatesModel *ActiveSkillsModel::delegatesModelForSkill(const QString &skillId) 0172 { 0173 0174 if (!skillAllowed(skillId)) { 0175 return nullptr; 0176 } 0177 0178 if (!skillId.isEmpty() && !m_skills.contains(skillId)) { 0179 return nullptr; 0180 } 0181 0182 DelegatesModel *model = m_delegatesModels.value(skillId); 0183 if (!model) { 0184 model = new DelegatesModel(this); 0185 m_delegatesModels[skillId] = model; 0186 const int row = m_skills.indexOf(skillId); 0187 emit dataChanged(index(row, 0), index(row, 0), {Delegates}); 0188 } 0189 0190 return model; 0191 } 0192 0193 QHash<QString, DelegatesModel*> ActiveSkillsModel::delegatesModels() const 0194 { 0195 return m_delegatesModels; 0196 } 0197 0198 bool ActiveSkillsModel::moveRows(const QModelIndex &sourceParent, int sourceRow, int count, const QModelIndex &destinationParent, int destinationChild) 0199 { 0200 if (sourceParent.isValid() || destinationParent.isValid()) { 0201 return false; 0202 } 0203 0204 if (count <= 0 || sourceRow == destinationChild || sourceRow < 0 || sourceRow >= m_skills.count() || 0205 destinationChild < 0 || destinationChild >= m_skills.count() || count - destinationChild > m_skills.count() - sourceRow) { 0206 return false; 0207 } 0208 const int sourceLast = sourceRow + count - 1; 0209 0210 //beginMoveRows wants indexes before the source rows are removed from the old order 0211 if (!beginMoveRows(sourceParent, sourceRow, sourceLast, destinationParent, destinationChild)) { 0212 return false; 0213 } 0214 0215 if (sourceRow < destinationChild) { 0216 for (int i = count - 1; i >= 0; --i) { 0217 m_skills.move(sourceRow + i, destinationChild - count + i); 0218 } 0219 } else { 0220 for (int i = 0; i < count; ++i) { 0221 m_skills.move(sourceRow + i, destinationChild + i); 0222 } 0223 } 0224 0225 endMoveRows(); 0226 0227 syncActiveIndex(); 0228 if (destinationChild == m_activeIndex) { 0229 checkGuiActivation(m_skills.first()); 0230 } 0231 0232 return true; 0233 } 0234 0235 bool ActiveSkillsModel::removeRows(int row, int count, const QModelIndex &parent) 0236 { 0237 if (row < 0 || count <= 0 || row + count > m_skills.count() || parent.isValid()) { 0238 return false; 0239 } 0240 0241 beginRemoveRows(parent, row, row + count - 1); 0242 for (auto it = m_skills.begin() + row; it < m_skills.begin() + row + count; ++it) { 0243 DelegatesModel *model = m_delegatesModels.value(*it); 0244 if (model) { 0245 model->deleteLater(); 0246 m_delegatesModels.remove(*it); 0247 } 0248 } 0249 m_skills.erase(m_skills.begin() + row, m_skills.begin() + row + count); 0250 0251 endRemoveRows(); 0252 syncActiveIndex(); 0253 return true; 0254 } 0255 0256 0257 int ActiveSkillsModel::rowCount(const QModelIndex &parent) const 0258 { 0259 if (parent.isValid()) { 0260 return 0; 0261 } 0262 return m_skills.count(); 0263 } 0264 0265 QVariant ActiveSkillsModel::data(const QModelIndex &index, int role) const 0266 { 0267 if (!index.isValid()) { 0268 return QVariant(); 0269 } 0270 const int row = index.row(); 0271 0272 if (row < 0 || row >= m_skills.count() || (role != SkillId && role != Delegates)) { 0273 return QVariant(); 0274 } 0275 0276 if (role == SkillId) { 0277 return m_skills[row]; 0278 //Delegates 0279 } else { 0280 return QVariant::fromValue(m_delegatesModels.value(m_skills[row])); 0281 } 0282 } 0283 0284 QHash<int, QByteArray> ActiveSkillsModel::roleNames() const 0285 { 0286 return { 0287 {SkillId, "skillId"}, 0288 {Delegates, "delegates"} 0289 }; 0290 } 0291