File indexing completed on 2024-05-05 05:40:28
0001 #include "model/filteredcharactermodel.h" 0002 0003 namespace campaign 0004 { 0005 0006 template <typename T> 0007 bool isNull(const T& value); 0008 0009 template <> 0010 bool isNull(const QPixmap& value) 0011 { 0012 return value.isNull(); 0013 } 0014 template <> 0015 bool isNull(const QString& value) 0016 { 0017 return value.isEmpty(); 0018 } 0019 0020 template <> 0021 bool isNull(const int& value) 0022 { 0023 return value == 0; 0024 } 0025 0026 template <> 0027 bool isNull(const bool& value) 0028 { 0029 return !value; 0030 } 0031 0032 template <typename T> 0033 bool isAccepted(FilteredCharacterModel::Definition def, T value) 0034 { 0035 if(def == FilteredCharacterModel::All) 0036 { 0037 return true; 0038 } 0039 else if(def == FilteredCharacterModel::With) 0040 { 0041 return !isNull(value); 0042 } 0043 else 0044 { 0045 return isNull(value); 0046 } 0047 } 0048 0049 FilteredCharacterModel::FilteredCharacterModel() 0050 { 0051 setDynamicSortFilter(true); 0052 0053 connect(this, &FilteredCharacterModel::searchChanged, this, &FilteredCharacterModel::invalidateFilter); 0054 connect(this, &FilteredCharacterModel::initiativeCmdDefChanged, this, &FilteredCharacterModel::invalidateFilter); 0055 connect(this, &FilteredCharacterModel::propertiesDefChanged, this, &FilteredCharacterModel::invalidateFilter); 0056 connect(this, &FilteredCharacterModel::shapeDefChanged, this, &FilteredCharacterModel::invalidateFilter); 0057 connect(this, &FilteredCharacterModel::actionDefChanged, this, &FilteredCharacterModel::invalidateFilter); 0058 connect(this, &FilteredCharacterModel::initiativeScoreDefChanged, this, &FilteredCharacterModel::invalidateFilter); 0059 connect(this, &FilteredCharacterModel::avatarDefinitionChanged, this, &FilteredCharacterModel::invalidateFilter); 0060 connect(this, &FilteredCharacterModel::advancedChanged, this, &FilteredCharacterModel::invalidateFilter); 0061 connect(this, &FilteredCharacterModel::excludeChanged, this, &FilteredCharacterModel::invalidateFilter); 0062 connect(this, &FilteredCharacterModel::tagsChanged, this, &FilteredCharacterModel::invalidateFilter); 0063 connect(this, &FilteredCharacterModel::excludeTagsChanged, this, &FilteredCharacterModel::invalidateFilter); 0064 connect(this, &FilteredCharacterModel::hlStateChanged, this, &FilteredCharacterModel::invalidateFilter); 0065 connect(this, &FilteredCharacterModel::characterStateIdChanged, this, &FilteredCharacterModel::invalidateFilter); 0066 } 0067 0068 FilteredCharacterModel::Definition FilteredCharacterModel::initiativeCmdDef() const 0069 { 0070 return m_initiativeCmdDef; 0071 } 0072 0073 void FilteredCharacterModel::setInitiativeCmdDef(FilteredCharacterModel::Definition newInitiativeCmdDef) 0074 { 0075 if(m_initiativeCmdDef == newInitiativeCmdDef) 0076 return; 0077 m_initiativeCmdDef= newInitiativeCmdDef; 0078 emit initiativeCmdDefChanged(); 0079 } 0080 0081 FilteredCharacterModel::Definition FilteredCharacterModel::propertiesDef() const 0082 { 0083 return m_propertiesDef; 0084 } 0085 0086 void FilteredCharacterModel::setPropertiesDef(Definition newPropertiesDef) 0087 { 0088 if(m_propertiesDef == newPropertiesDef) 0089 return; 0090 m_propertiesDef= newPropertiesDef; 0091 emit propertiesDefChanged(); 0092 } 0093 0094 FilteredCharacterModel::Definition FilteredCharacterModel::shapeDef() const 0095 { 0096 return m_shapeDef; 0097 } 0098 0099 void FilteredCharacterModel::setShapeDef(FilteredCharacterModel::Definition newShapeDef) 0100 { 0101 if(m_shapeDef == newShapeDef) 0102 return; 0103 m_shapeDef= newShapeDef; 0104 emit shapeDefChanged(); 0105 } 0106 0107 FilteredCharacterModel::Definition FilteredCharacterModel::actionDef() const 0108 { 0109 return m_actionDef; 0110 } 0111 0112 void FilteredCharacterModel::setActionDef(FilteredCharacterModel::Definition newActionDef) 0113 { 0114 if(m_actionDef == newActionDef) 0115 return; 0116 m_actionDef= newActionDef; 0117 emit actionDefChanged(); 0118 } 0119 0120 FilteredCharacterModel::Definition FilteredCharacterModel::initiativeScoreDef() const 0121 { 0122 return m_initiativeScoreDef; 0123 } 0124 0125 void FilteredCharacterModel::setInitiativeScoreDef(FilteredCharacterModel::Definition newInitiativeScoreDef) 0126 { 0127 if(m_initiativeScoreDef == newInitiativeScoreDef) 0128 return; 0129 m_initiativeScoreDef= newInitiativeScoreDef; 0130 emit initiativeScoreDefChanged(); 0131 } 0132 0133 FilteredCharacterModel::Definition FilteredCharacterModel::avatarDefinition() const 0134 { 0135 return m_avatarDefinition; 0136 } 0137 0138 void FilteredCharacterModel::setAvatarDefinition(FilteredCharacterModel::Definition newAvatarDefinition) 0139 { 0140 if(m_avatarDefinition == newAvatarDefinition) 0141 return; 0142 m_avatarDefinition= newAvatarDefinition; 0143 emit avatarDefinitionChanged(); 0144 } 0145 0146 bool FilteredCharacterModel::advanced() const 0147 { 0148 return m_advanced; 0149 } 0150 0151 void FilteredCharacterModel::setAdvanced(bool newAdvanced) 0152 { 0153 if(m_advanced == newAdvanced) 0154 return; 0155 m_advanced= newAdvanced; 0156 emit advancedChanged(); 0157 } 0158 0159 const QString& FilteredCharacterModel::exclude() const 0160 { 0161 return m_exclude; 0162 } 0163 0164 void FilteredCharacterModel::setExclude(const QString& newExclude) 0165 { 0166 if(m_exclude == newExclude) 0167 return; 0168 m_exclude= newExclude; 0169 emit excludeChanged(); 0170 } 0171 0172 const QString& FilteredCharacterModel::tags() const 0173 { 0174 return m_tags; 0175 } 0176 0177 void FilteredCharacterModel::setTags(const QString& newTags) 0178 { 0179 if(m_tags == newTags) 0180 return; 0181 m_tags= newTags; 0182 emit tagsChanged(); 0183 } 0184 0185 const QString& FilteredCharacterModel::excludeTags() const 0186 { 0187 return m_excludeTags; 0188 } 0189 0190 void FilteredCharacterModel::setExcludeTags(const QString& newExcludeTags) 0191 { 0192 if(m_excludeTags == newExcludeTags) 0193 return; 0194 m_excludeTags= newExcludeTags; 0195 emit excludeTagsChanged(); 0196 } 0197 0198 QString FilteredCharacterModel::search() const 0199 { 0200 return m_search; 0201 } 0202 0203 void FilteredCharacterModel::setSearch(const QString& search) 0204 { 0205 if(search == m_search) 0206 return; 0207 m_search= search; 0208 emit searchChanged(); 0209 } 0210 0211 bool FilteredCharacterModel::filterAcceptsRow(int source_row, const QModelIndex& source_parent) const 0212 { 0213 using nm= NonPlayableCharacterModel; 0214 auto nameIndex= sourceModel()->index(source_row, 0, source_parent); 0215 auto name= sourceModel()->data(nameIndex, nm::RoleName).toString(); 0216 auto tagList= sourceModel()->data(nameIndex, nm::RoleTags).toStringList(); 0217 0218 bool accepted= true; 0219 if(advanced()) 0220 { 0221 auto gmdetails= sourceModel()->data(nameIndex, nm::RoleGmDetails).toString(); 0222 // clang-format off 0223 auto avatar= isAccepted<QPixmap>(m_avatarDefinition, sourceModel()->data(nameIndex, nm::RoleAvatar).value<QPixmap>()); 0224 auto initScore= isAccepted<bool>(m_initiativeScoreDef, sourceModel()->data(nameIndex, nm::RoleHasInitiative).toBool()); 0225 auto initCmd= isAccepted<QString>(m_initiativeCmdDef, sourceModel()->data(nameIndex, nm::RoleInitCommand).toString()); 0226 auto actions= isAccepted<int>(m_actionDef, sourceModel()->data(nameIndex, nm::RoleActionCount).toInt()); 0227 auto properties= isAccepted<int>(m_propertiesDef, sourceModel()->data(nameIndex, nm::RolePropertiesCount).toInt()); 0228 auto shapes= isAccepted<int>(m_shapeDef, sourceModel()->data(nameIndex, nm::RoleShapeCount).toInt()); 0229 auto details= isAccepted<QString>(m_gmdetailsDef, gmdetails); 0230 auto characterState= m_characterStateId.isEmpty() ? true : (m_characterStateId == sourceModel()->data(nameIndex, nm::RoleState).toString()); 0231 0232 auto current = sourceModel()->data(nameIndex, nm::RoleCurrentHp).toInt(); 0233 auto min = sourceModel()->data(nameIndex, nm::RoleMinHp).toInt(); 0234 auto max = sourceModel()->data(nameIndex, nm::RoleMaxHp).toInt(); 0235 auto health = m_hlState == FilteredCharacterModel::HS_All ? true : m_hlState == FilteredCharacterModel::HS_Full ? current == max : m_hlState == FilteredCharacterModel::HS_Dead ? min == current : (current > min && current < max); 0236 // clang-format on 0237 0238 auto nameval= m_search.isEmpty() ? true : name.contains(m_search, Qt::CaseInsensitive); 0239 auto gmDetails= m_gmdetails.isEmpty() ? true : gmdetails.contains(m_gmdetails, Qt::CaseInsensitive); 0240 auto exclude= !(m_exclude.isEmpty() ? false : name.contains(m_exclude, Qt::CaseInsensitive)); 0241 auto tags= m_tags.isEmpty() ? true : tagList.join(QString()).contains(m_tags, Qt::CaseInsensitive); 0242 auto excludeTags 0243 = !(m_excludeTags.isEmpty() ? false : tagList.join(QString()).contains(m_excludeTags, Qt::CaseInsensitive)); 0244 0245 accepted= avatar & initScore & actions & properties & shapes & details & nameval & exclude & tags & excludeTags 0246 & initCmd & health & gmDetails & characterState; 0247 } 0248 else 0249 { 0250 auto nameVal= m_search.isEmpty() ? true : name.contains(m_search, Qt::CaseInsensitive); 0251 auto tags= m_search.isEmpty() ? true : tagList.join(QString()).contains(m_search, Qt::CaseInsensitive); 0252 accepted= (nameVal || tags); 0253 } 0254 0255 return accepted; 0256 } 0257 0258 bool FilteredCharacterModel::lessThan(const QModelIndex& source_left, const QModelIndex& source_right) const 0259 { 0260 auto data1= source_left.data().toString(); 0261 auto data2= source_right.data().toString(); 0262 0263 return data1 < data2; 0264 } 0265 0266 QString FilteredCharacterModel::characterStateId() const 0267 { 0268 return m_characterStateId; 0269 } 0270 0271 void FilteredCharacterModel::setCharacterStateId(const QString& newCharaceterStateId) 0272 { 0273 if(m_characterStateId == newCharaceterStateId) 0274 return; 0275 m_characterStateId= newCharaceterStateId; 0276 emit characterStateIdChanged(); 0277 } 0278 0279 } // namespace campaign