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