mirror of
https://github.com/qgis/QGIS.git
synced 2025-11-29 00:06:58 -05:00
[QgsLocator] add the capability of adding group for elements within the same filter
This commit is contained in:
parent
56104bcd12
commit
c1e16969f3
@ -45,6 +45,8 @@ Constructor for QgsLocatorResult.
|
|||||||
|
|
||||||
double score;
|
double score;
|
||||||
|
|
||||||
|
QString group;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class QgsLocatorFilter : QObject
|
class QgsLocatorFilter : QObject
|
||||||
|
|||||||
@ -26,6 +26,8 @@ in order to ensure correct sorting of results by priority and match level.
|
|||||||
%End
|
%End
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
static const int NoGroup;
|
||||||
|
|
||||||
enum Role
|
enum Role
|
||||||
{
|
{
|
||||||
ResultDataRole,
|
ResultDataRole,
|
||||||
@ -33,6 +35,7 @@ in order to ensure correct sorting of results by priority and match level.
|
|||||||
ResultFilterPriorityRole,
|
ResultFilterPriorityRole,
|
||||||
ResultScoreRole,
|
ResultScoreRole,
|
||||||
ResultFilterNameRole,
|
ResultFilterNameRole,
|
||||||
|
ResultFilterGroupSortingRole,
|
||||||
};
|
};
|
||||||
|
|
||||||
QgsLocatorModel( QObject *parent /TransferThis/ = 0 );
|
QgsLocatorModel( QObject *parent /TransferThis/ = 0 );
|
||||||
|
|||||||
@ -409,9 +409,9 @@ sub detect_comment_block{
|
|||||||
}
|
}
|
||||||
|
|
||||||
# Detect if line is a non method member declaration
|
# 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{
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -82,6 +82,15 @@ class CORE_EXPORT QgsLocatorResult
|
|||||||
*/
|
*/
|
||||||
double score = 0.5;
|
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();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -15,12 +15,14 @@
|
|||||||
* *
|
* *
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
|
#include <QFont>
|
||||||
|
|
||||||
#include "qgslocatormodel.h"
|
#include "qgslocatormodel.h"
|
||||||
#include "qgslocator.h"
|
#include "qgslocator.h"
|
||||||
#include "qgsapplication.h"
|
#include "qgsapplication.h"
|
||||||
#include "qgslogger.h"
|
#include "qgslogger.h"
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// QgsLocatorModel
|
// QgsLocatorModel
|
||||||
//
|
//
|
||||||
@ -41,6 +43,7 @@ void QgsLocatorModel::clear()
|
|||||||
beginResetModel();
|
beginResetModel();
|
||||||
mResults.clear();
|
mResults.clear();
|
||||||
mFoundResultsFromFilterNames.clear();
|
mFoundResultsFromFilterNames.clear();
|
||||||
|
mFoundResultsFilterGroups.clear();
|
||||||
endResetModel();
|
endResetModel();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -76,8 +79,14 @@ QVariant QgsLocatorModel::data( const QModelIndex &index, int role ) const
|
|||||||
case Name:
|
case Name:
|
||||||
if ( !mResults.at( index.row() ).filter )
|
if ( !mResults.at( index.row() ).filter )
|
||||||
return mResults.at( index.row() ).result.displayString;
|
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;
|
return mResults.at( index.row() ).filterTitle;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
QString groupTitle = mResults.at( index.row() ).groupTitle;
|
||||||
|
groupTitle.prepend( " " );
|
||||||
|
return groupTitle;
|
||||||
|
}
|
||||||
case Description:
|
case Description:
|
||||||
if ( !mResults.at( index.row() ).filter )
|
if ( !mResults.at( index.row() ).filter )
|
||||||
return mResults.at( index.row() ).result.description;
|
return mResults.at( index.row() ).result.description;
|
||||||
@ -87,6 +96,19 @@ QVariant QgsLocatorModel::data( const QModelIndex &index, int role ) const
|
|||||||
break;
|
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:
|
case Qt::DecorationRole:
|
||||||
switch ( index.column() )
|
switch ( index.column() )
|
||||||
{
|
{
|
||||||
@ -112,10 +134,8 @@ QVariant QgsLocatorModel::data( const QModelIndex &index, int role ) const
|
|||||||
return QVariant();
|
return QVariant();
|
||||||
|
|
||||||
case ResultTypeRole:
|
case ResultTypeRole:
|
||||||
if ( mResults.at( index.row() ).filter )
|
// 0 for filter title, the group otherwise, 9999 if no group
|
||||||
return 0;
|
return mResults.at( index.row() ).groupSorting;
|
||||||
else
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
case ResultScoreRole:
|
case ResultScoreRole:
|
||||||
if ( mResults.at( index.row() ).filter )
|
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();
|
return mResults.at( index.row() ).result.filter->displayName();
|
||||||
else
|
else
|
||||||
return mResults.at( index.row() ).filterTitle;
|
return mResults.at( index.row() ).filterTitle;
|
||||||
|
|
||||||
|
case ResultFilterGroupSortingRole:
|
||||||
|
if ( mResults.at( index.row() ).groupTitle.isEmpty() )
|
||||||
|
return 1;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return QVariant();
|
return QVariant();
|
||||||
@ -146,7 +172,7 @@ Qt::ItemFlags QgsLocatorModel::flags( const QModelIndex &index ) const
|
|||||||
return QAbstractTableModel::flags( index );
|
return QAbstractTableModel::flags( index );
|
||||||
|
|
||||||
Qt::ItemFlags flags = 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 );
|
flags = flags & ~( Qt::ItemIsSelectable | Qt::ItemIsEnabled );
|
||||||
}
|
}
|
||||||
@ -159,6 +185,7 @@ void QgsLocatorModel::addResult( const QgsLocatorResult &result )
|
|||||||
if ( mDeferredClear )
|
if ( mDeferredClear )
|
||||||
{
|
{
|
||||||
mFoundResultsFromFilterNames.clear();
|
mFoundResultsFromFilterNames.clear();
|
||||||
|
mFoundResultsFilterGroups.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
int pos = mResults.size();
|
int pos = mResults.size();
|
||||||
@ -166,13 +193,21 @@ void QgsLocatorModel::addResult( const QgsLocatorResult &result )
|
|||||||
if ( addingFilter )
|
if ( addingFilter )
|
||||||
mFoundResultsFromFilterNames << result.filter->name();
|
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 )
|
if ( mDeferredClear )
|
||||||
{
|
{
|
||||||
beginResetModel();
|
beginResetModel();
|
||||||
mResults.clear();
|
mResults.clear();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
beginInsertRows( QModelIndex(), pos, pos + ( addingFilter ? 1 : 0 ) );
|
beginInsertRows( QModelIndex(), pos, pos + ( static_cast<int>( addingFilter ) + static_cast<int>( addingGroup ) ) );
|
||||||
|
|
||||||
if ( addingFilter )
|
if ( addingFilter )
|
||||||
{
|
{
|
||||||
@ -181,8 +216,21 @@ void QgsLocatorModel::addResult( const QgsLocatorResult &result )
|
|||||||
entry.filter = result.filter;
|
entry.filter = result.filter;
|
||||||
mResults << entry;
|
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 entry;
|
||||||
entry.result = result;
|
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;
|
mResults << entry;
|
||||||
|
|
||||||
if ( mDeferredClear )
|
if ( mDeferredClear )
|
||||||
@ -279,12 +327,18 @@ bool QgsLocatorProxyModel::lessThan( const QModelIndex &left, const QModelIndex
|
|||||||
if ( leftFilter != rightFilter )
|
if ( leftFilter != rightFilter )
|
||||||
return QString::localeAwareCompare( leftFilter, rightFilter ) < 0;
|
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 leftTypeRole = sourceModel()->data( left, QgsLocatorModel::ResultTypeRole ).toInt();
|
||||||
int rightTypeRole = sourceModel()->data( right, QgsLocatorModel::ResultTypeRole ).toInt();
|
int rightTypeRole = sourceModel()->data( right, QgsLocatorModel::ResultTypeRole ).toInt();
|
||||||
if ( leftTypeRole != rightTypeRole )
|
if ( leftTypeRole != rightTypeRole )
|
||||||
return 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
|
// sort filter's results by score
|
||||||
double leftScore = sourceModel()->data( left, QgsLocatorModel::ResultScoreRole ).toDouble();
|
double leftScore = sourceModel()->data( left, QgsLocatorModel::ResultScoreRole ).toDouble();
|
||||||
double rightScore = sourceModel()->data( right, QgsLocatorModel::ResultScoreRole ).toDouble();
|
double rightScore = sourceModel()->data( right, QgsLocatorModel::ResultScoreRole ).toDouble();
|
||||||
|
|||||||
@ -45,6 +45,8 @@ class CORE_EXPORT QgsLocatorModel : public QAbstractTableModel
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
static const int NoGroup = 9999;
|
||||||
|
|
||||||
//! Custom model roles
|
//! Custom model roles
|
||||||
enum Role
|
enum Role
|
||||||
{
|
{
|
||||||
@ -53,6 +55,7 @@ class CORE_EXPORT QgsLocatorModel : public QAbstractTableModel
|
|||||||
ResultFilterPriorityRole, //!< Result priority, used by QgsLocatorProxyModel for sorting roles.
|
ResultFilterPriorityRole, //!< Result priority, used by QgsLocatorProxyModel for sorting roles.
|
||||||
ResultScoreRole, //!< Result match score, used by QgsLocatorProxyModel for sorting roles.
|
ResultScoreRole, //!< Result match score, used by QgsLocatorProxyModel for sorting roles.
|
||||||
ResultFilterNameRole, //!< Associated filter name which created the result
|
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;
|
QgsLocatorResult result;
|
||||||
QString filterTitle;
|
QString filterTitle;
|
||||||
QgsLocatorFilter *filter = nullptr;
|
QgsLocatorFilter *filter = nullptr;
|
||||||
|
QString groupTitle = QString();
|
||||||
|
int groupSorting = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
QList<Entry> mResults;
|
QList<Entry> mResults;
|
||||||
QSet<QString> mFoundResultsFromFilterNames;
|
QSet<QString> mFoundResultsFromFilterNames;
|
||||||
|
QMap<QgsLocatorFilter *, QStringList> mFoundResultsFilterGroups;
|
||||||
bool mDeferredClear = false;
|
bool mDeferredClear = false;
|
||||||
QTimer mDeferredClearTimer;
|
QTimer mDeferredClearTimer;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -252,8 +252,15 @@ void QgsLocatorWidget::addResult( const QgsLocatorResult &result )
|
|||||||
mLocatorModel->addResult( result );
|
mLocatorModel->addResult( result );
|
||||||
if ( selectFirst )
|
if ( selectFirst )
|
||||||
{
|
{
|
||||||
int row = mProxyModel->flags( mProxyModel->index( 0, 0 ) ) & Qt::ItemIsSelectable ? 0 : 1;
|
int row = -1;
|
||||||
mResultsView->setCurrentIndex( mProxyModel->index( row, 0 ) );
|
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 ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user