@@ -63,7 +63,9 @@ QgsLocatorWidget::QgsLocatorWidget( QWidget *parent )
63
63
mResultsContainer ->setLayout ( containerLayout );
64
64
mResultsContainer ->hide ();
65
65
66
- mResultsView ->setModel ( mLocatorModel );
66
+ mProxyModel = new QgsLocatorProxyModel ( mLocatorModel );
67
+ mProxyModel ->setSourceModel ( mLocatorModel );
68
+ mResultsView ->setModel ( mProxyModel );
67
69
mResultsView ->recalculateSize ();
68
70
69
71
connect ( mLocator , &QgsLocator::foundResult, this , &QgsLocatorWidget::addResult );
@@ -191,10 +193,10 @@ bool QgsLocatorWidget::eventFilter( QObject *obj, QEvent *event )
191
193
192
194
void QgsLocatorWidget::addResult ( const QgsLocatorResult &result )
193
195
{
194
- bool selectFirst = mLocatorModel ->rowCount () == 0 ;
196
+ bool selectFirst = mProxyModel ->rowCount () == 0 ;
195
197
mLocatorModel ->addResult ( result );
196
198
if ( selectFirst )
197
- mResultsView ->setCurrentIndex ( mLocatorModel ->index ( 0 , 0 ) );
199
+ mResultsView ->setCurrentIndex ( mProxyModel ->index ( 1 , 0 ) );
198
200
}
199
201
200
202
void QgsLocatorWidget::updateResults ( const QString &text )
@@ -234,7 +236,7 @@ void QgsLocatorWidget::acceptCurrentEntry()
234
236
if ( !index.isValid () )
235
237
return ;
236
238
237
- QgsLocatorResult result = mLocatorModel ->data ( index, QgsLocatorModel::ResultDataRole ).value < QgsLocatorResult >();
239
+ QgsLocatorResult result = mProxyModel ->data ( index, QgsLocatorModel::ResultDataRole ).value < QgsLocatorResult >();
238
240
mResultsContainer ->hide ();
239
241
mLineEdit ->clearFocus ();
240
242
result.filter ->triggerResult ( result );
@@ -266,6 +268,7 @@ void QgsLocatorModel::clear()
266
268
{
267
269
beginResetModel ();
268
270
mResults .clear ();
271
+ mFoundResultsFromFilterNames .clear ();
269
272
endResetModel ();
270
273
}
271
274
@@ -289,22 +292,73 @@ QVariant QgsLocatorModel::data( const QModelIndex &index, int role ) const
289
292
{
290
293
case Qt::DisplayRole:
291
294
case Qt::EditRole:
292
- return mResults .at ( index.row () ).displayString ;
295
+ {
296
+ if ( mResults .at ( index.row () ).filterTitle .isEmpty () )
297
+ return mResults .at ( index.row () ).result .displayString ;
298
+ else
299
+ return mResults .at ( index.row () ).filterTitle ;
300
+ }
293
301
294
302
case Qt::DecorationRole:
295
- return mResults .at ( index.row () ).icon ;
303
+ if ( mResults .at ( index.row () ).filterTitle .isEmpty () )
304
+ return mResults .at ( index.row () ).result .icon ;
305
+ else
306
+ return QVariant ();
296
307
297
308
case ResultDataRole:
298
- return QVariant::fromValue ( mResults .at ( index.row () ) );
309
+ if ( mResults .at ( index.row () ).filterTitle .isEmpty () )
310
+ return QVariant::fromValue ( mResults .at ( index.row () ).result );
311
+ else
312
+ return QVariant ();
313
+
314
+ case ResultTypeRole:
315
+ if ( mResults .at ( index.row () ).filterTitle .isEmpty () )
316
+ return 1 ;
317
+ else
318
+ return 0 ;
319
+
320
+ case ResultFilterNameRole:
321
+ if ( mResults .at ( index.row () ).filterTitle .isEmpty () )
322
+ return mResults .at ( index.row () ).result .filter ->displayName ();
323
+ else
324
+ return mResults .at ( index.row () ).filterTitle ;
299
325
}
300
326
301
327
return QVariant ();
302
328
}
303
329
330
+ Qt::ItemFlags QgsLocatorModel::flags ( const QModelIndex &index ) const
331
+ {
332
+ if ( !index.isValid () || index.row () < 0 || index.column () < 0 ||
333
+ index.row () >= rowCount ( QModelIndex () ) || index.column () >= columnCount ( QModelIndex () ) )
334
+ return QAbstractListModel::flags ( index );
335
+
336
+ Qt::ItemFlags flags = QAbstractListModel::flags ( index );
337
+ if ( !mResults .at ( index.row () ).filterTitle .isEmpty () )
338
+ {
339
+ flags = flags & ~( Qt::ItemIsSelectable | Qt::ItemIsEnabled );
340
+ }
341
+ return flags;
342
+
343
+ }
344
+
304
345
void QgsLocatorModel::addResult ( const QgsLocatorResult &result )
305
346
{
306
- beginInsertRows ( QModelIndex (), mResults .size (), mResults .size () );
307
- mResults << result;
347
+ int pos = mResults .size ();
348
+ bool addingFilter = !mFoundResultsFromFilterNames .contains ( result.filter ->name () );
349
+ if ( addingFilter )
350
+ mFoundResultsFromFilterNames << result.filter ->name ();
351
+
352
+ beginInsertRows ( QModelIndex (), pos, pos + ( addingFilter ? 1 : 0 ) );
353
+ if ( addingFilter )
354
+ {
355
+ Entry entry;
356
+ entry.filterTitle = result.filter ->displayName ();
357
+ mResults << entry;
358
+ }
359
+ Entry entry;
360
+ entry.result = result;
361
+ mResults << entry;
308
362
endInsertRows ();
309
363
}
310
364
@@ -352,3 +406,29 @@ void QgsLocatorResultsView::selectPreviousResult()
352
406
353
407
// /@endcond
354
408
409
+
410
+ QgsLocatorProxyModel::QgsLocatorProxyModel ( QObject *parent )
411
+ : QSortFilterProxyModel( parent )
412
+ {
413
+ setDynamicSortFilter ( true );
414
+ setSortLocaleAware ( true );
415
+ setFilterCaseSensitivity ( Qt::CaseInsensitive );
416
+ sort ( 0 );
417
+ }
418
+
419
+ bool QgsLocatorProxyModel::lessThan ( const QModelIndex &left, const QModelIndex &right ) const
420
+ {
421
+ QString leftFilter = sourceModel ()->data ( left, QgsLocatorModel::ResultFilterNameRole ).toString ();
422
+ QString rightFilter = sourceModel ()->data ( right, QgsLocatorModel::ResultFilterNameRole ).toString ();
423
+ if ( leftFilter != rightFilter )
424
+ return QString::localeAwareCompare ( leftFilter, rightFilter ) < 0 ;
425
+
426
+ int leftTypeRole = sourceModel ()->data ( left, QgsLocatorModel::ResultTypeRole ).toInt ();
427
+ int rightTypeRole = sourceModel ()->data ( right, QgsLocatorModel::ResultTypeRole ).toInt ();
428
+ if ( leftTypeRole != rightTypeRole )
429
+ return leftTypeRole < rightTypeRole;
430
+
431
+ leftFilter = sourceModel ()->data ( left, Qt::DisplayRole ).toString ();
432
+ rightFilter = sourceModel ()->data ( right, Qt::DisplayRole ).toString ();
433
+ return QString::localeAwareCompare ( leftFilter, rightFilter ) < 0 ;
434
+ }
0 commit comments