Reputation: 1441
I am performing a sort on the following collection of strings using QString::localeAwareCompare:
Search term used: "Mountain"
Results:
The order is sorted lexically according to QString::compare. Ultimately I would like the order to have the following rules:
Match contained in word sorted lexically
Does anyone know how this might be achieved? I am able to implement a custom sort of some kind.
EDIT:
Here is some janky code I have tried to get exact matches to the top, which works.
bool CardDatabaseDisplayModel::lessThan(const QModelIndex &left, const QModelIndex &right) const {
QString leftString = sourceModel()->data(left).toString();
QString rightString = sourceModel()->data(right).toString();
if (leftString.compare(cardName, Qt::CaseInsensitive) == 0) {// exact match should be at top
return true;
}
if (rightString.compare(cardName, Qt::CaseInsensitive) == 0) {// exact match should be at top
return false;
}
return QString::localeAwareCompare(leftString, rightString) < 0;
}
Upvotes: 3
Views: 300
Reputation: 7320
Here is a way you could complete your current code. It tries to sort from the most special to the most general case: exact match, match-plus-stuff, everything else.
bool CardDatabaseDisplayModel::lessThan(const QModelIndex &left,
const QModelIndex &right) const {
QString leftString = sourceModel()->data(left).toString();
QString rightString = sourceModel()->data(right).toString();
// The exact match (if any) should be at the top
if (leftString.compare(cardName, Qt::CaseInsensitive) == 0)
return true;
if (rightString.compare(cardName, Qt::CaseInsensitive) == 0)
return false;
// We know that neither is the perfect match.
// But is either a match-plus-some-stuff ?
bool isLeftType2 = leftString.startsWith(cardName, Qt::CaseInsensitive);
bool isRightType2 = rightString.startsWith(cardName, Qt::CaseInsensitive);
if (isLeftType2 && !isRightType2)
return true;
if (isRigthType2 && !isLeftType2)
return false;
// At this point we're sorting two matches of the same type
// Either both are matches-plus-some-stuff or partial matches
return QString::localeAwareCompare(leftString, rightString) < 0;
}
I assumed that something like "Mountaineer" alone would be type 2 and not type 3, you could add a +" "
in the comparisons if you don't want that.
Upvotes: 2