Skip to content

Commit 6649d2b

Browse files
committed
Sort filter results so closer matches appear higher
A closer match means more of the text is matched, ie a short string inside a long string is penalised
1 parent a53516d commit 6649d2b

File tree

6 files changed

+30
-0
lines changed

6 files changed

+30
-0
lines changed

python/gui/locator/qgslocatorfilter.sip

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,11 @@ class QgsLocatorResult
5252
Icon for result.
5353
%End
5454

55+
double score = 0.5;
56+
%Docstring
57+
Match score, from 0 - 1, where 1 represents a perfect match.
58+
%End
59+
5560
};
5661

5762
class QgsLocatorFilter : QObject

python/plugins/processing/gui/AlgorithmLocatorFilter.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,10 @@ def fetchResults(self,string,context,feedback):
6464
result.displayString = a.displayName()
6565
result.icon = a.icon()
6666
result.userData = a.id()
67+
if string.lower() in a.displayName().lower():
68+
result.score = float(len(string)) / len(a.displayName())
69+
else:
70+
result.score = 0
6771
self.resultFetched.emit(result)
6872

6973
def triggerResult(self, result):

src/app/locator/qgsinbuiltlocatorfilters.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ void QgsLayerTreeLocatorFilter::fetchResults( const QString &string, const QgsLo
4747
result.displayString = layer->layer()->name();
4848
result.userData = layer->layerId();
4949
result.icon = QgsMapLayerModel::iconForLayer( layer->layer() );
50+
result.score = static_cast< double >( string.length() ) / layer->layer()->name().length();
5051
emit resultFetched( result );
5152
}
5253
}
@@ -81,6 +82,7 @@ void QgsLayoutLocatorFilter::fetchResults( const QString &string, const QgsLocat
8182
result.displayString = composition->name();
8283
result.userData = composition->name();
8384
//result.icon = QgsMapLayerModel::iconForLayer( layer->layer() );
85+
result.score = static_cast< double >( string.length() ) / composition->name().length();
8486
emit resultFetched( result );
8587
}
8688
}
@@ -155,6 +157,7 @@ void QgsActionLocatorFilter::searchActions( const QString &string, QWidget *pare
155157
result.displayString = searchText;
156158
result.userData = QVariant::fromValue( action );
157159
result.icon = action->icon();
160+
result.score = static_cast< double >( string.length() ) / searchText.length();
158161
emit resultFetched( result );
159162
found << action;
160163
}

src/gui/locator/qgslocatorfilter.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,11 @@ class GUI_EXPORT QgsLocatorResult
7272
*/
7373
QIcon icon;
7474

75+
/**
76+
* Match score, from 0 - 1, where 1 represents a perfect match.
77+
*/
78+
double score = 0.5;
79+
7580
};
7681

7782
/**

src/gui/locator/qgslocatorwidget.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,12 @@ QVariant QgsLocatorModel::data( const QModelIndex &index, int role ) const
317317
else
318318
return 1;
319319

320+
case ResultScoreRole:
321+
if ( mResults.at( index.row() ).filter )
322+
return 0;
323+
else
324+
return ( mResults.at( index.row() ).result.score );
325+
320326
case ResultFilterPriorityRole:
321327
if ( !mResults.at( index.row() ).filter )
322328
return mResults.at( index.row() ).result.filter->priority();
@@ -443,6 +449,12 @@ bool QgsLocatorProxyModel::lessThan( const QModelIndex &left, const QModelIndex
443449
if ( leftTypeRole != rightTypeRole )
444450
return leftTypeRole < rightTypeRole;
445451

452+
// sort filter's results by score
453+
double leftScore = sourceModel()->data( left, QgsLocatorModel::ResultScoreRole ).toDouble();
454+
double rightScore = sourceModel()->data( right, QgsLocatorModel::ResultScoreRole ).toDouble();
455+
if ( !qgsDoubleNear( leftScore, rightScore ) )
456+
return leftScore > rightScore;
457+
446458
// lastly sort filter's results by string
447459
leftFilter = sourceModel()->data( left, Qt::DisplayRole ).toString();
448460
rightFilter = sourceModel()->data( right, Qt::DisplayRole ).toString();

src/gui/locator/qgslocatorwidget.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ class QgsLocatorModel : public QAbstractListModel
128128
ResultDataRole = Qt::UserRole + 1, //!< QgsLocatorResult data
129129
ResultTypeRole,
130130
ResultFilterPriorityRole,
131+
ResultScoreRole,
131132
ResultFilterNameRole,
132133
};
133134

0 commit comments

Comments
 (0)