Allow speciyfing the priority for filters

Higher priority (i.e. more important) filter results get shown
first. This means filters like project layers & composers will
show above 'cruder' filters like the actions/processing filters.
This commit is contained in:
Nyall Dawson 2017-05-11 14:32:06 +10:00
parent 0f80df09a7
commit b33ce0bf47
6 changed files with 64 additions and 8 deletions

View File

@ -66,6 +66,15 @@ class QgsLocatorFilter : QObject
%End
public:
enum Priority
{
Highest,
High,
Medium,
Low,
Lowest
};
QgsLocatorFilter( QObject *parent = 0 );
%Docstring
Constructor for QgsLocatorFilter.
@ -85,6 +94,13 @@ class QgsLocatorFilter : QObject
:rtype: str
%End
virtual Priority priority() const;
%Docstring
Returns the priority for the filter, which controls how results are
ordered in the locator.
:rtype: Priority
%End
virtual void fetchResults( const QString &string, const QgsLocatorContext &context, QgsFeedback *feedback ) = 0;
%Docstring
Retrieves the filter results for a specified search ``string``. The ``context``

View File

@ -45,6 +45,9 @@ class AlgorithmLocatorFilter(QgsLocatorFilter):
def displayName(self):
return self.tr('Processing Algorithms')
def priority(self):
return QgsLocatorFilter.Low
def fetchResults(self,string,context,feedback):
for a in QgsApplication.processingRegistry().algorithms():
if feedback.isCanceled():

View File

@ -30,6 +30,7 @@ class QgsLayerTreeLocatorFilter : public QgsLocatorFilter
QgsLayerTreeLocatorFilter( QObject *parent = nullptr );
virtual QString name() const override { return QStringLiteral( "layertree" ); }
virtual QString displayName() const override { return tr( "Project layers" ); }
virtual Priority priority() const override { return Highest; }
void fetchResults( const QString &string, const QgsLocatorContext &context, QgsFeedback *feedback ) override;
void triggerResult( const QgsLocatorResult &result ) override;
@ -45,6 +46,7 @@ class QgsLayoutLocatorFilter : public QgsLocatorFilter
QgsLayoutLocatorFilter( QObject *parent = nullptr );
virtual QString name() const override { return QStringLiteral( "layouts" ); }
virtual QString displayName() const override { return tr( "Project layouts" ); }
virtual Priority priority() const override { return Highest; }
void fetchResults( const QString &string, const QgsLocatorContext &context, QgsFeedback *feedback ) override;
void triggerResult( const QgsLocatorResult &result ) override;
@ -60,6 +62,7 @@ class QgsActionLocatorFilter : public QgsLocatorFilter
QgsActionLocatorFilter( const QList<QWidget *> &parentObjectsForActions, QObject *parent = nullptr );
virtual QString name() const override { return QStringLiteral( "actions" ); }
virtual QString displayName() const override { return tr( "Actions" ); }
virtual Priority priority() const override { return Lowest; }
void fetchResults( const QString &string, const QgsLocatorContext &context, QgsFeedback *feedback ) override;
void triggerResult( const QgsLocatorResult &result ) override;

View File

@ -86,6 +86,16 @@ class GUI_EXPORT QgsLocatorFilter : public QObject
public:
//! Filter priority. Controls the order of results in the locator.
enum Priority
{
Highest, //!< Highest priority
High, //!< High priority
Medium, //!< Medium priority
Low, //!< Low priority
Lowest //!< Lowest priority
};
/**
* Constructor for QgsLocatorFilter.
*/
@ -103,6 +113,12 @@ class GUI_EXPORT QgsLocatorFilter : public QObject
*/
virtual QString displayName() const = 0;
/**
* Returns the priority for the filter, which controls how results are
* ordered in the locator.
*/
virtual Priority priority() const { return Medium; }
/**
* Retrieves the filter results for a specified search \a string. The \a context
* argument encapsulates the context relating to the search (such as a map

View File

@ -42,7 +42,7 @@ QgsLocatorWidget::QgsLocatorWidget( QWidget *parent )
setSizePolicy( sizePolicy );
setMinimumSize( QSize( 200, 0 ) );
QHBoxLayout *layout = new QHBoxLayout( this );
QHBoxLayout *layout = new QHBoxLayout();
layout->setMargin( 0 );
layout->setContentsMargins( 0, 0, 0, 0 );
layout->addWidget( mLineEdit );
@ -293,32 +293,38 @@ QVariant QgsLocatorModel::data( const QModelIndex &index, int role ) const
case Qt::DisplayRole:
case Qt::EditRole:
{
if ( mResults.at( index.row() ).filterTitle.isEmpty() )
if ( !mResults.at( index.row() ).filter )
return mResults.at( index.row() ).result.displayString;
else
return mResults.at( index.row() ).filterTitle;
}
case Qt::DecorationRole:
if ( mResults.at( index.row() ).filterTitle.isEmpty() )
if ( !mResults.at( index.row() ).filter )
return mResults.at( index.row() ).result.icon;
else
return QVariant();
case ResultDataRole:
if ( mResults.at( index.row() ).filterTitle.isEmpty() )
if ( !mResults.at( index.row() ).filter )
return QVariant::fromValue( mResults.at( index.row() ).result );
else
return QVariant();
case ResultTypeRole:
if ( mResults.at( index.row() ).filterTitle.isEmpty() )
return 1;
else
if ( mResults.at( index.row() ).filter )
return 0;
else
return 1;
case ResultFilterPriorityRole:
if ( !mResults.at( index.row() ).filter )
return mResults.at( index.row() ).result.filter->priority();
else
return mResults.at( index.row() ).filter->priority();
case ResultFilterNameRole:
if ( mResults.at( index.row() ).filterTitle.isEmpty() )
if ( !mResults.at( index.row() ).filter )
return mResults.at( index.row() ).result.filter->displayName();
else
return mResults.at( index.row() ).filterTitle;
@ -354,6 +360,7 @@ void QgsLocatorModel::addResult( const QgsLocatorResult &result )
{
Entry entry;
entry.filterTitle = result.filter->displayName();
entry.filter = result.filter;
mResults << entry;
}
Entry entry;
@ -418,16 +425,25 @@ QgsLocatorProxyModel::QgsLocatorProxyModel( QObject *parent )
bool QgsLocatorProxyModel::lessThan( const QModelIndex &left, const QModelIndex &right ) const
{
// first go by filter priority
int leftFilterPriority = sourceModel()->data( left, QgsLocatorModel::ResultFilterPriorityRole ).toInt();
int rightFilterPriority = sourceModel()->data( right, QgsLocatorModel::ResultFilterPriorityRole ).toInt();
if ( leftFilterPriority != rightFilterPriority )
return leftFilterPriority < rightFilterPriority;
// then filter name
QString leftFilter = sourceModel()->data( left, QgsLocatorModel::ResultFilterNameRole ).toString();
QString rightFilter = sourceModel()->data( right, QgsLocatorModel::ResultFilterNameRole ).toString();
if ( leftFilter != rightFilter )
return QString::localeAwareCompare( leftFilter, rightFilter ) < 0;
// then make sure filter title appears before filter's results
int leftTypeRole = sourceModel()->data( left, QgsLocatorModel::ResultTypeRole ).toInt();
int rightTypeRole = sourceModel()->data( right, QgsLocatorModel::ResultTypeRole ).toInt();
if ( leftTypeRole != rightTypeRole )
return leftTypeRole < rightTypeRole;
// lastly sort filter's results by string
leftFilter = sourceModel()->data( left, Qt::DisplayRole ).toString();
rightFilter = sourceModel()->data( right, Qt::DisplayRole ).toString();
return QString::localeAwareCompare( leftFilter, rightFilter ) < 0;

View File

@ -127,6 +127,7 @@ class QgsLocatorModel : public QAbstractListModel
{
ResultDataRole = Qt::UserRole + 1, //!< QgsLocatorResult data
ResultTypeRole,
ResultFilterPriorityRole,
ResultFilterNameRole,
};
@ -158,6 +159,7 @@ class QgsLocatorModel : public QAbstractListModel
{
QgsLocatorResult result;
QString filterTitle;
QgsLocatorFilter *filter = nullptr;
};
QList<Entry> mResults;