Skip to content

Commit c1e1696

Browse files
committedMay 18, 2018
[QgsLocator] add the capability of adding group for elements within the same filter
1 parent 56104bc commit c1e1696

File tree

7 files changed

+93
-12
lines changed

7 files changed

+93
-12
lines changed
 

‎python/core/auto_generated/locator/qgslocatorfilter.sip.in

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ Constructor for QgsLocatorResult.
4545

4646
double score;
4747

48+
QString group;
49+
4850
};
4951

5052
class QgsLocatorFilter : QObject

‎python/core/auto_generated/locator/qgslocatormodel.sip.in

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,16 @@ in order to ensure correct sorting of results by priority and match level.
2626
%End
2727
public:
2828

29+
static const int NoGroup;
30+
2931
enum Role
3032
{
3133
ResultDataRole,
3234
ResultTypeRole,
3335
ResultFilterPriorityRole,
3436
ResultScoreRole,
3537
ResultFilterNameRole,
38+
ResultFilterGroupSortingRole,
3639
};
3740

3841
QgsLocatorModel( QObject *parent /TransferThis/ = 0 );

‎scripts/sipify.pl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -409,9 +409,9 @@ sub detect_comment_block{
409409
}
410410

411411
# Detect if line is a non method member declaration
412-
# https://regex101.com/r/gUBZUk/13
412+
# https://regex101.com/r/gUBZUk/14
413413
sub detect_non_method_member{
414-
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+\])?)+;/;
414+
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+\])?)+;/;
415415
return 0;
416416
}
417417

‎src/core/locator/qgslocatorfilter.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,15 @@ class CORE_EXPORT QgsLocatorResult
8282
*/
8383
double score = 0.5;
8484

85+
/**
86+
* Group the results by categories
87+
* If left as empty string, this means that results are all shown without being grouped.
88+
* If a group is given, the results will be grouped by \a group under a header.
89+
* \note This should be translated.
90+
* \since 3.2
91+
*/
92+
QString group = QString();
93+
8594
};
8695

8796
/**

‎src/core/locator/qgslocatormodel.cpp

Lines changed: 62 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,14 @@
1515
* *
1616
***************************************************************************/
1717

18+
#include <QFont>
1819

1920
#include "qgslocatormodel.h"
2021
#include "qgslocator.h"
2122
#include "qgsapplication.h"
2223
#include "qgslogger.h"
2324

25+
2426
//
2527
// QgsLocatorModel
2628
//
@@ -41,6 +43,7 @@ void QgsLocatorModel::clear()
4143
beginResetModel();
4244
mResults.clear();
4345
mFoundResultsFromFilterNames.clear();
46+
mFoundResultsFilterGroups.clear();
4447
endResetModel();
4548
}
4649

@@ -76,8 +79,14 @@ QVariant QgsLocatorModel::data( const QModelIndex &index, int role ) const
7679
case Name:
7780
if ( !mResults.at( index.row() ).filter )
7881
return mResults.at( index.row() ).result.displayString;
79-
else
82+
else if ( mResults.at( index.row() ).filter && mResults.at( index.row() ).groupSorting == 0 )
8083
return mResults.at( index.row() ).filterTitle;
84+
else
85+
{
86+
QString groupTitle = mResults.at( index.row() ).groupTitle;
87+
groupTitle.prepend( " " );
88+
return groupTitle;
89+
}
8190
case Description:
8291
if ( !mResults.at( index.row() ).filter )
8392
return mResults.at( index.row() ).result.description;
@@ -87,6 +96,19 @@ QVariant QgsLocatorModel::data( const QModelIndex &index, int role ) const
8796
break;
8897
}
8998

99+
case Qt::FontRole:
100+
if ( index.column() == Name && !mResults.at( index.row() ).groupTitle.isEmpty() )
101+
{
102+
QFont font;
103+
font.setItalic( true );
104+
return font;
105+
}
106+
else
107+
{
108+
return QVariant();
109+
}
110+
break;
111+
90112
case Qt::DecorationRole:
91113
switch ( index.column() )
92114
{
@@ -112,10 +134,8 @@ QVariant QgsLocatorModel::data( const QModelIndex &index, int role ) const
112134
return QVariant();
113135

114136
case ResultTypeRole:
115-
if ( mResults.at( index.row() ).filter )
116-
return 0;
117-
else
118-
return 1;
137+
// 0 for filter title, the group otherwise, 9999 if no group
138+
return mResults.at( index.row() ).groupSorting;
119139

120140
case ResultScoreRole:
121141
if ( mResults.at( index.row() ).filter )
@@ -134,6 +154,12 @@ QVariant QgsLocatorModel::data( const QModelIndex &index, int role ) const
134154
return mResults.at( index.row() ).result.filter->displayName();
135155
else
136156
return mResults.at( index.row() ).filterTitle;
157+
158+
case ResultFilterGroupSortingRole:
159+
if ( mResults.at( index.row() ).groupTitle.isEmpty() )
160+
return 1;
161+
else
162+
return 0;
137163
}
138164

139165
return QVariant();
@@ -146,7 +172,7 @@ Qt::ItemFlags QgsLocatorModel::flags( const QModelIndex &index ) const
146172
return QAbstractTableModel::flags( index );
147173

148174
Qt::ItemFlags flags = QAbstractTableModel::flags( index );
149-
if ( !mResults.at( index.row() ).filterTitle.isEmpty() )
175+
if ( mResults.at( index.row() ).filter )
150176
{
151177
flags = flags & ~( Qt::ItemIsSelectable | Qt::ItemIsEnabled );
152178
}
@@ -159,20 +185,29 @@ void QgsLocatorModel::addResult( const QgsLocatorResult &result )
159185
if ( mDeferredClear )
160186
{
161187
mFoundResultsFromFilterNames.clear();
188+
mFoundResultsFilterGroups.clear();
162189
}
163190

164191
int pos = mResults.size();
165192
bool addingFilter = !result.filter->displayName().isEmpty() && !mFoundResultsFromFilterNames.contains( result.filter->name() );
166193
if ( addingFilter )
167194
mFoundResultsFromFilterNames << result.filter->name();
168195

196+
bool addingGroup = !result.group.isEmpty() && ( !mFoundResultsFilterGroups.contains( result.filter )
197+
|| !mFoundResultsFilterGroups.value( result.filter ).contains( result.group ) );
198+
if ( addingGroup )
199+
{
200+
if ( !mFoundResultsFilterGroups.contains( result.filter ) )
201+
mFoundResultsFilterGroups[result.filter] = QStringList();
202+
mFoundResultsFilterGroups[result.filter] << result.group ;
203+
}
169204
if ( mDeferredClear )
170205
{
171206
beginResetModel();
172207
mResults.clear();
173208
}
174209
else
175-
beginInsertRows( QModelIndex(), pos, pos + ( addingFilter ? 1 : 0 ) );
210+
beginInsertRows( QModelIndex(), pos, pos + ( static_cast<int>( addingFilter ) + static_cast<int>( addingGroup ) ) );
176211

177212
if ( addingFilter )
178213
{
@@ -181,8 +216,21 @@ void QgsLocatorModel::addResult( const QgsLocatorResult &result )
181216
entry.filter = result.filter;
182217
mResults << entry;
183218
}
219+
if ( addingGroup )
220+
{
221+
Entry entry;
222+
entry.filterTitle = result.filter->displayName();
223+
entry.groupTitle = result.group;
224+
// the sorting of groups will be achieved by order of adding groups
225+
// this could be customized by adding the extra info to QgsLocatorResult
226+
entry.groupSorting = mFoundResultsFilterGroups[result.filter].count();
227+
entry.filter = result.filter;
228+
mResults << entry;
229+
}
184230
Entry entry;
185231
entry.result = result;
232+
// keep the group title empty to allow differecing group title from results
233+
entry.groupSorting = result.group.isEmpty() ? NoGroup : mFoundResultsFilterGroups[result.filter].count();
186234
mResults << entry;
187235

188236
if ( mDeferredClear )
@@ -279,12 +327,18 @@ bool QgsLocatorProxyModel::lessThan( const QModelIndex &left, const QModelIndex
279327
if ( leftFilter != rightFilter )
280328
return QString::localeAwareCompare( leftFilter, rightFilter ) < 0;
281329

282-
// then make sure filter title appears before filter's results
330+
// then make sure filter title or group appears before filter's results
283331
int leftTypeRole = sourceModel()->data( left, QgsLocatorModel::ResultTypeRole ).toInt();
284332
int rightTypeRole = sourceModel()->data( right, QgsLocatorModel::ResultTypeRole ).toInt();
285333
if ( leftTypeRole != rightTypeRole )
286334
return leftTypeRole < rightTypeRole;
287335

336+
// make sure group title are above
337+
int leftGroupRole = sourceModel()->data( left, QgsLocatorModel::ResultFilterGroupSortingRole ).toInt();
338+
int rightGroupRole = sourceModel()->data( right, QgsLocatorModel::ResultFilterGroupSortingRole ).toInt();
339+
if ( leftGroupRole != rightGroupRole )
340+
return leftGroupRole < rightGroupRole;
341+
288342
// sort filter's results by score
289343
double leftScore = sourceModel()->data( left, QgsLocatorModel::ResultScoreRole ).toDouble();
290344
double rightScore = sourceModel()->data( right, QgsLocatorModel::ResultScoreRole ).toDouble();

‎src/core/locator/qgslocatormodel.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ class CORE_EXPORT QgsLocatorModel : public QAbstractTableModel
4545

4646
public:
4747

48+
static const int NoGroup = 9999;
49+
4850
//! Custom model roles
4951
enum Role
5052
{
@@ -53,6 +55,7 @@ class CORE_EXPORT QgsLocatorModel : public QAbstractTableModel
5355
ResultFilterPriorityRole, //!< Result priority, used by QgsLocatorProxyModel for sorting roles.
5456
ResultScoreRole, //!< Result match score, used by QgsLocatorProxyModel for sorting roles.
5557
ResultFilterNameRole, //!< Associated filter name which created the result
58+
ResultFilterGroupSortingRole, //!< Group results within the same filter results
5659
};
5760

5861
/**
@@ -99,10 +102,13 @@ class CORE_EXPORT QgsLocatorModel : public QAbstractTableModel
99102
QgsLocatorResult result;
100103
QString filterTitle;
101104
QgsLocatorFilter *filter = nullptr;
105+
QString groupTitle = QString();
106+
int groupSorting = 0;
102107
};
103108

104109
QList<Entry> mResults;
105110
QSet<QString> mFoundResultsFromFilterNames;
111+
QMap<QgsLocatorFilter *, QStringList> mFoundResultsFilterGroups;
106112
bool mDeferredClear = false;
107113
QTimer mDeferredClearTimer;
108114
};

‎src/gui/locator/qgslocatorwidget.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -252,8 +252,15 @@ void QgsLocatorWidget::addResult( const QgsLocatorResult &result )
252252
mLocatorModel->addResult( result );
253253
if ( selectFirst )
254254
{
255-
int row = mProxyModel->flags( mProxyModel->index( 0, 0 ) ) & Qt::ItemIsSelectable ? 0 : 1;
256-
mResultsView->setCurrentIndex( mProxyModel->index( row, 0 ) );
255+
int row = -1;
256+
bool selectable = false;
257+
while ( !selectable && row < mProxyModel->rowCount() )
258+
{
259+
row++;
260+
selectable = mProxyModel->flags( mProxyModel->index( row, 0 ) ).testFlag( Qt::ItemIsSelectable );
261+
}
262+
if ( selectable )
263+
mResultsView->setCurrentIndex( mProxyModel->index( row, 0 ) );
257264
}
258265
}
259266

0 commit comments

Comments
 (0)
Please sign in to comment.