[QgsLocator] add the capability of adding group for elements within the same filter

This commit is contained in:
Denis Rouzaud 2018-05-17 13:11:10 -04:00
parent 56104bcd12
commit c1e16969f3
7 changed files with 93 additions and 12 deletions

View File

@ -45,6 +45,8 @@ Constructor for QgsLocatorResult.
double score;
QString group;
};
class QgsLocatorFilter : QObject

View File

@ -26,6 +26,8 @@ in order to ensure correct sorting of results by priority and match level.
%End
public:
static const int NoGroup;
enum Role
{
ResultDataRole,
@ -33,6 +35,7 @@ in order to ensure correct sorting of results by priority and match level.
ResultFilterPriorityRole,
ResultScoreRole,
ResultFilterNameRole,
ResultFilterGroupSortingRole,
};
QgsLocatorModel( QObject *parent /TransferThis/ = 0 );

View File

@ -409,9 +409,9 @@ sub detect_comment_block{
}
# Detect if line is a non method member declaration
# https://regex101.com/r/gUBZUk/13
# https://regex101.com/r/gUBZUk/14
sub detect_non_method_member{
return 1 if $LINE =~ m/^\s*(?:template\s*<\w+>\s+)?(?:(const|mutable|static|friend|unsigned)\s+)*\w+(::\w+)?(<([\w<> *&,()]|::)+>)?(,?\s+\*?\w+( = (-?\d+(\.\d+)?|((QMap|QList)<[^()]+>\(\))|(\w+::)*\w+(\([^()]+\))?)|\[\d+\])?)+;/;
return 1 if $LINE =~ m/^\s*(?:template\s*<\w+>\s+)?(?:(const|mutable|static|friend|unsigned)\s+)*\w+(::\w+)?(<([\w<> *&,()]|::)+>)?(,?\s+\*?\w+( = (-?\d+(\.\d+)?|((QMap|QList)<[^()]+>\(\))|(\w+::)*\w+(\([^()]?\))?)|\[\d+\])?)+;/;
return 0;
}

View File

@ -82,6 +82,15 @@ class CORE_EXPORT QgsLocatorResult
*/
double score = 0.5;
/**
* Group the results by categories
* If left as empty string, this means that results are all shown without being grouped.
* If a group is given, the results will be grouped by \a group under a header.
* \note This should be translated.
* \since 3.2
*/
QString group = QString();
};
/**

View File

@ -15,12 +15,14 @@
* *
***************************************************************************/
#include <QFont>
#include "qgslocatormodel.h"
#include "qgslocator.h"
#include "qgsapplication.h"
#include "qgslogger.h"
//
// QgsLocatorModel
//
@ -41,6 +43,7 @@ void QgsLocatorModel::clear()
beginResetModel();
mResults.clear();
mFoundResultsFromFilterNames.clear();
mFoundResultsFilterGroups.clear();
endResetModel();
}
@ -76,8 +79,14 @@ QVariant QgsLocatorModel::data( const QModelIndex &index, int role ) const
case Name:
if ( !mResults.at( index.row() ).filter )
return mResults.at( index.row() ).result.displayString;
else
else if ( mResults.at( index.row() ).filter && mResults.at( index.row() ).groupSorting == 0 )
return mResults.at( index.row() ).filterTitle;
else
{
QString groupTitle = mResults.at( index.row() ).groupTitle;
groupTitle.prepend( " " );
return groupTitle;
}
case Description:
if ( !mResults.at( index.row() ).filter )
return mResults.at( index.row() ).result.description;
@ -87,6 +96,19 @@ QVariant QgsLocatorModel::data( const QModelIndex &index, int role ) const
break;
}
case Qt::FontRole:
if ( index.column() == Name && !mResults.at( index.row() ).groupTitle.isEmpty() )
{
QFont font;
font.setItalic( true );
return font;
}
else
{
return QVariant();
}
break;
case Qt::DecorationRole:
switch ( index.column() )
{
@ -112,10 +134,8 @@ QVariant QgsLocatorModel::data( const QModelIndex &index, int role ) const
return QVariant();
case ResultTypeRole:
if ( mResults.at( index.row() ).filter )
return 0;
else
return 1;
// 0 for filter title, the group otherwise, 9999 if no group
return mResults.at( index.row() ).groupSorting;
case ResultScoreRole:
if ( mResults.at( index.row() ).filter )
@ -134,6 +154,12 @@ QVariant QgsLocatorModel::data( const QModelIndex &index, int role ) const
return mResults.at( index.row() ).result.filter->displayName();
else
return mResults.at( index.row() ).filterTitle;
case ResultFilterGroupSortingRole:
if ( mResults.at( index.row() ).groupTitle.isEmpty() )
return 1;
else
return 0;
}
return QVariant();
@ -146,7 +172,7 @@ Qt::ItemFlags QgsLocatorModel::flags( const QModelIndex &index ) const
return QAbstractTableModel::flags( index );
Qt::ItemFlags flags = QAbstractTableModel::flags( index );
if ( !mResults.at( index.row() ).filterTitle.isEmpty() )
if ( mResults.at( index.row() ).filter )
{
flags = flags & ~( Qt::ItemIsSelectable | Qt::ItemIsEnabled );
}
@ -159,6 +185,7 @@ void QgsLocatorModel::addResult( const QgsLocatorResult &result )
if ( mDeferredClear )
{
mFoundResultsFromFilterNames.clear();
mFoundResultsFilterGroups.clear();
}
int pos = mResults.size();
@ -166,13 +193,21 @@ void QgsLocatorModel::addResult( const QgsLocatorResult &result )
if ( addingFilter )
mFoundResultsFromFilterNames << result.filter->name();
bool addingGroup = !result.group.isEmpty() && ( !mFoundResultsFilterGroups.contains( result.filter )
|| !mFoundResultsFilterGroups.value( result.filter ).contains( result.group ) );
if ( addingGroup )
{
if ( !mFoundResultsFilterGroups.contains( result.filter ) )
mFoundResultsFilterGroups[result.filter] = QStringList();
mFoundResultsFilterGroups[result.filter] << result.group ;
}
if ( mDeferredClear )
{
beginResetModel();
mResults.clear();
}
else
beginInsertRows( QModelIndex(), pos, pos + ( addingFilter ? 1 : 0 ) );
beginInsertRows( QModelIndex(), pos, pos + ( static_cast<int>( addingFilter ) + static_cast<int>( addingGroup ) ) );
if ( addingFilter )
{
@ -181,8 +216,21 @@ void QgsLocatorModel::addResult( const QgsLocatorResult &result )
entry.filter = result.filter;
mResults << entry;
}
if ( addingGroup )
{
Entry entry;
entry.filterTitle = result.filter->displayName();
entry.groupTitle = result.group;
// the sorting of groups will be achieved by order of adding groups
// this could be customized by adding the extra info to QgsLocatorResult
entry.groupSorting = mFoundResultsFilterGroups[result.filter].count();
entry.filter = result.filter;
mResults << entry;
}
Entry entry;
entry.result = result;
// keep the group title empty to allow differecing group title from results
entry.groupSorting = result.group.isEmpty() ? NoGroup : mFoundResultsFilterGroups[result.filter].count();
mResults << entry;
if ( mDeferredClear )
@ -279,12 +327,18 @@ bool QgsLocatorProxyModel::lessThan( const QModelIndex &left, const QModelIndex
if ( leftFilter != rightFilter )
return QString::localeAwareCompare( leftFilter, rightFilter ) < 0;
// then make sure filter title appears before filter's results
// then make sure filter title or group 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;
// make sure group title are above
int leftGroupRole = sourceModel()->data( left, QgsLocatorModel::ResultFilterGroupSortingRole ).toInt();
int rightGroupRole = sourceModel()->data( right, QgsLocatorModel::ResultFilterGroupSortingRole ).toInt();
if ( leftGroupRole != rightGroupRole )
return leftGroupRole < rightGroupRole;
// sort filter's results by score
double leftScore = sourceModel()->data( left, QgsLocatorModel::ResultScoreRole ).toDouble();
double rightScore = sourceModel()->data( right, QgsLocatorModel::ResultScoreRole ).toDouble();

View File

@ -45,6 +45,8 @@ class CORE_EXPORT QgsLocatorModel : public QAbstractTableModel
public:
static const int NoGroup = 9999;
//! Custom model roles
enum Role
{
@ -53,6 +55,7 @@ class CORE_EXPORT QgsLocatorModel : public QAbstractTableModel
ResultFilterPriorityRole, //!< Result priority, used by QgsLocatorProxyModel for sorting roles.
ResultScoreRole, //!< Result match score, used by QgsLocatorProxyModel for sorting roles.
ResultFilterNameRole, //!< Associated filter name which created the result
ResultFilterGroupSortingRole, //!< Group results within the same filter results
};
/**
@ -99,10 +102,13 @@ class CORE_EXPORT QgsLocatorModel : public QAbstractTableModel
QgsLocatorResult result;
QString filterTitle;
QgsLocatorFilter *filter = nullptr;
QString groupTitle = QString();
int groupSorting = 0;
};
QList<Entry> mResults;
QSet<QString> mFoundResultsFromFilterNames;
QMap<QgsLocatorFilter *, QStringList> mFoundResultsFilterGroups;
bool mDeferredClear = false;
QTimer mDeferredClearTimer;
};

View File

@ -252,8 +252,15 @@ void QgsLocatorWidget::addResult( const QgsLocatorResult &result )
mLocatorModel->addResult( result );
if ( selectFirst )
{
int row = mProxyModel->flags( mProxyModel->index( 0, 0 ) ) & Qt::ItemIsSelectable ? 0 : 1;
mResultsView->setCurrentIndex( mProxyModel->index( row, 0 ) );
int row = -1;
bool selectable = false;
while ( !selectable && row < mProxyModel->rowCount() )
{
row++;
selectable = mProxyModel->flags( mProxyModel->index( row, 0 ) ).testFlag( Qt::ItemIsSelectable );
}
if ( selectable )
mResultsView->setCurrentIndex( mProxyModel->index( row, 0 ) );
}
}