Added OR and AND based search to modlist and pluginlist.

A space now means AND and "OR ; | ||" mean OR. OR always wins.
This commit is contained in:
Al
2019-01-18 01:34:18 +01:00
parent 9c364c0dff
commit 0d04ba1873
2 changed files with 104 additions and 42 deletions
+71 -40
View File
@@ -357,59 +357,90 @@ bool ModListSortProxy::filterMatchesModOr(ModInfo::Ptr info, bool enabled) const
bool ModListSortProxy::filterMatchesMod(ModInfo::Ptr info, bool enabled) const
{
bool display = true;
if (!m_CurrentFilter.isEmpty()) {
display = false;
bool display = false;
QString filterCopy = QString(m_CurrentFilter);
filterCopy.replace("||", ";").replace("OR", ";").replace("|", ";");
QStringList ORList = filterCopy.split(";", QString::SkipEmptyParts);
// Search by name
if (!display &&
m_EnabledColumns[ModList::COL_NAME] &&
info->name().contains(m_CurrentFilter, Qt::CaseInsensitive)) {
display = true;
}
bool segmentGood = true;
// Search by notes
if (!display &&
m_EnabledColumns[ModList::COL_NOTES] &&
info->comments().contains(m_CurrentFilter, Qt::CaseInsensitive)) {
display = true;
}
//split in ORSegments that internally use AND logic
for (auto& ORSegment : ORList) {
QStringList ANDKeywords = ORSegment.split(" ", QString::SkipEmptyParts);
segmentGood = true;
bool foundKeyword = false;
// Search by Nexus ID
if (!display &&
m_EnabledColumns[ModList::COL_MODID]) {
bool ok;
int filterID = m_CurrentFilter.toInt(&ok);
if (ok) {
int modID = info->getNexusID();
while (modID > 0) {
if (modID == filterID) {
display = true;
break;
}
modID = (int)(modID / 10);
//check each word in the segment for match, each word needs to be matched but it doesn't matter where.
for (auto& currentKeyword : ANDKeywords) {
foundKeyword = false;
//search keyword in name
if (m_EnabledColumns[ModList::COL_NAME] &&
info->name().contains(currentKeyword, Qt::CaseInsensitive)) {
foundKeyword = true;
}
}
}
// Search by categories
if (!display &&
m_EnabledColumns[ModList::COL_CATEGORY]) {
for (auto category : info->categories()) {
if (category.contains(m_CurrentFilter, Qt::CaseInsensitive)) {
display = true;
// Search by notes
if (!foundKeyword &&
m_EnabledColumns[ModList::COL_NOTES] &&
info->comments().contains(currentKeyword, Qt::CaseInsensitive)) {
foundKeyword = true;
}
// Search by categories
if (!foundKeyword &&
m_EnabledColumns[ModList::COL_CATEGORY]) {
for (auto category : info->categories()) {
if (category.contains(currentKeyword, Qt::CaseInsensitive)) {
foundKeyword = true;
break;
}
}
}
// Search by Nexus ID
if (!foundKeyword &&
m_EnabledColumns[ModList::COL_MODID]) {
bool ok;
int filterID = currentKeyword.toInt(&ok);
if (ok) {
int modID = info->getNexusID();
while (modID > 0) {
if (modID == filterID) {
foundKeyword = true;
break;
}
modID = (int)(modID / 10);
}
}
}
if (!foundKeyword) {
//currentKeword is missing from everything, AND fails and we need to check next ORsegment
segmentGood = false;
break;
}
}//for ANDKeywords loop
if (segmentGood) {
//the last AND loop didn't break so the ORSegments is true so mod matches filter
display = true;
break;
}
}//for ORList loop
if (!display) {
return false;
}
}
if (!display) {
return false;
}
}//if (!m_CurrentFilter.isEmpty())
if (m_FilterMode == FILTER_AND) {
return filterMatchesModAnd(info, enabled);
} else {
}
else {
return filterMatchesModOr(info, enabled);
}
}
+33 -2
View File
@@ -139,7 +139,38 @@ bool PluginListSortProxy::dropMimeData(const QMimeData *data, Qt::DropAction act
bool PluginListSortProxy::filterMatchesPlugin(const QString &plugin) const
{
return m_CurrentFilter.isEmpty() ||
plugin.contains(m_CurrentFilter, Qt::CaseInsensitive);
if (!m_CurrentFilter.isEmpty()) {
bool display = false;
QString filterCopy = QString(m_CurrentFilter);
filterCopy.replace("||", ";").replace("OR", ";").replace("|", ";");
QStringList ORList = filterCopy.split(";", QString::SkipEmptyParts);
bool segmentGood = true;
//split in ORSegments that internally use AND logic
for (auto& ORSegment : ORList) {
QStringList ANDKeywords = ORSegment.split(" ", QString::SkipEmptyParts);
segmentGood = true;
//check each word in the segment for match, each word needs to be matched but it doesn't matter where.
for (auto& currentKeyword : ANDKeywords) {
if (!plugin.contains(currentKeyword, Qt::CaseInsensitive)) {
segmentGood = false;
break;
}
}
if (segmentGood) {
//the last AND loop didn't break so the ORSegments is true so mod matches filter
return true;
}
}//for ORList loop
return false;
}
else
return true;
}