Skip to content

Commit fec31f8

Browse files
committedDec 13, 2017
Sort browser items
Implements a sort key for browser items, allowing them to be correctly sorted. Fixes #17591
1 parent 7a1a4ed commit fec31f8

File tree

8 files changed

+84
-1
lines changed

8 files changed

+84
-1
lines changed
 

‎python/core/qgsbrowsermodel.sip

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ class QgsBrowserModel : QAbstractItemModel
2323
{
2424
PathRole,
2525
CommentRole,
26+
SortRole,
2627
};
2728

2829
virtual Qt::ItemFlags flags( const QModelIndex &index ) const;

‎python/core/qgsdataitem.sip

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,27 @@ Create path component replacing path separators
271271
:rtype: str
272272
%End
273273

274+
virtual QVariant sortKey() const;
275+
%Docstring
276+
Returns the sorting key for the item. By default name() is returned,
277+
but setSortKey() can be used to set a custom sort key for the item.
278+
279+
Alternatively subclasses can override this method to return a custom
280+
sort key.
281+
282+
.. seealso:: :py:func:`setSortKey()`
283+
.. versionadded:: 3.0
284+
:rtype: QVariant
285+
%End
286+
287+
void setSortKey( const QVariant &key );
288+
%Docstring
289+
Sets a custom sorting ``key`` for the item.
290+
.. seealso:: :py:func:`sortKey()`
291+
.. versionadded:: 3.0
292+
%End
293+
294+
274295
void setIcon( const QIcon &icon );
275296
void setIconName( const QString &iconName );
276297

@@ -307,6 +328,7 @@ Move object and all its descendants to thread
307328
%End
308329

309330

331+
310332
public slots:
311333

312334
virtual void deleteLater();
@@ -669,6 +691,9 @@ Icon for favorites group
669691
:rtype: QIcon
670692
%End
671693

694+
virtual QVariant sortKey() const;
695+
696+
672697
};
673698

674699
class QgsZipItem : QgsDataCollectionItem

‎src/core/qgsbrowsermodel.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ void QgsBrowserModel::updateProjectHome()
7272
mProjectHome = home.isNull() ? nullptr : new QgsDirectoryItem( nullptr, tr( "Project home" ), home, "project:" + home );
7373
if ( mProjectHome )
7474
{
75+
mProjectHome->setSortKey( QStringLiteral( " 1" ) );
7576
connectItem( mProjectHome );
7677

7778
beginInsertRows( QModelIndex(), 0, 0 );
@@ -84,8 +85,9 @@ void QgsBrowserModel::addRootItems()
8485
{
8586
updateProjectHome();
8687

87-
// give the home directory a prominent second place
88+
// give the home directory a prominent third place
8889
QgsDirectoryItem *item = new QgsDirectoryItem( nullptr, tr( "Home" ), QDir::homePath(), "home:" + QDir::homePath() );
90+
item->setSortKey( QStringLiteral( " 2" ) );
8991
QStyle *style = QApplication::style();
9092
QIcon homeIcon( style->standardPixmap( QStyle::SP_DirHomeIcon ) );
9193
item->setIcon( homeIcon );
@@ -109,6 +111,7 @@ void QgsBrowserModel::addRootItems()
109111
continue;
110112

111113
QgsDirectoryItem *item = new QgsDirectoryItem( nullptr, path, path );
114+
item->setSortKey( QStringLiteral( " 3 %1" ).arg( path ) );
112115

113116
connectItem( item );
114117
mRootItems << item;
@@ -212,6 +215,10 @@ QVariant QgsBrowserModel::data( const QModelIndex &index, int role ) const
212215
{
213216
return item->name();
214217
}
218+
else if ( role == QgsBrowserModel::SortRole )
219+
{
220+
return item->sortKey();
221+
}
215222
else if ( role == Qt::ToolTipRole )
216223
{
217224
return item->toolTip();

‎src/core/qgsbrowsermodel.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ class CORE_EXPORT QgsBrowserModel : public QAbstractItemModel
6464
{
6565
PathRole = Qt::UserRole, //!< Item path used to access path in the tree, see QgsDataItem::mPath
6666
CommentRole = Qt::UserRole + 1, //!< Item comment
67+
SortRole, //!< Custom sort role, see QgsDataItem::sortKey()
6768
};
6869
// implemented methods from QAbstractItemModel for read-only access
6970

‎src/core/qgsdataitem.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,11 @@ QIcon QgsFavoritesItem::iconFavorites()
102102
return QgsApplication::getThemeIcon( QStringLiteral( "/mIconFavourites.png" ) );
103103
}
104104

105+
QVariant QgsFavoritesItem::sortKey() const
106+
{
107+
return QStringLiteral( " 0" );
108+
}
109+
105110
QIcon QgsZipItem::iconZip()
106111
{
107112
return QgsApplication::getThemeIcon( QStringLiteral( "/mIconZip.png" ) );
@@ -150,6 +155,16 @@ QString QgsDataItem::pathComponent( const QString &string )
150155
return QString( string ).replace( QRegExp( "[\\\\/]" ), QStringLiteral( "|" ) );
151156
}
152157

158+
QVariant QgsDataItem::sortKey() const
159+
{
160+
return mSortKey.isValid() ? mSortKey : name();
161+
}
162+
163+
void QgsDataItem::setSortKey( const QVariant &key )
164+
{
165+
mSortKey = key;
166+
}
167+
153168
void QgsDataItem::deleteLater()
154169
{
155170
QgsDebugMsgLevel( "path = " + path(), 3 );
@@ -753,6 +768,10 @@ QVector<QgsDataItem *> QgsDirectoryItem::createChildren()
753768
continue;
754769

755770
QgsDirectoryItem *item = new QgsDirectoryItem( this, subdir, subdirPath, path );
771+
772+
// we want directories shown before files
773+
item->setSortKey( QStringLiteral( " %1" ).arg( subdir ) );
774+
756775
// propagate signals up to top
757776

758777
children.append( item );

‎src/core/qgsdataitem.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,26 @@ class CORE_EXPORT QgsDataItem : public QObject
255255
//! Create path component replacing path separators
256256
static QString pathComponent( const QString &component );
257257

258+
/**
259+
* Returns the sorting key for the item. By default name() is returned,
260+
* but setSortKey() can be used to set a custom sort key for the item.
261+
*
262+
* Alternatively subclasses can override this method to return a custom
263+
* sort key.
264+
*
265+
* \see setSortKey()
266+
* \since QGIS 3.0
267+
*/
268+
virtual QVariant sortKey() const;
269+
270+
/**
271+
* Sets a custom sorting \a key for the item.
272+
* \see sortKey()
273+
* \since QGIS 3.0
274+
*/
275+
void setSortKey( const QVariant &key );
276+
277+
258278
// Because QIcon (QPixmap) must not be used in outside the GUI thread, it is
259279
// not possible to set mIcon in constructor. Either use mIconName/setIconName()
260280
// or implement icon().
@@ -303,6 +323,9 @@ class CORE_EXPORT QgsDataItem : public QObject
303323
QIcon mIcon;
304324
QMap<QString, QIcon> mIconMap;
305325

326+
//! Custom sort key. If invalid, name() will be used for sorting instead.
327+
QVariant mSortKey;
328+
306329
public slots:
307330

308331
/**
@@ -631,6 +654,8 @@ class CORE_EXPORT QgsFavoritesItem : public QgsDataCollectionItem
631654
//! Icon for favorites group
632655
static QIcon iconFavorites();
633656

657+
QVariant sortKey() const override;
658+
634659
private:
635660
QVector<QgsDataItem *> createChildren( const QString &favDir );
636661
};

‎src/gui/qgsbrowserdockwidget.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,8 @@ void QgsBrowserDockWidget::showEvent( QShowEvent *e )
122122
mBrowserView->setSettingsSection( objectName().toLower() ); // to distinguish 2 or more instances of the browser
123123
mBrowserView->setBrowserModel( mModel );
124124
mBrowserView->setModel( mProxyModel );
125+
mBrowserView->setSortingEnabled( true );
126+
mBrowserView->sortByColumn( 0, Qt::AscendingOrder );
125127
// provide a horizontal scroll bar instead of using ellipse (...) for longer items
126128
mBrowserView->setTextElideMode( Qt::ElideNone );
127129
mBrowserView->header()->setSectionResizeMode( 0, QHeaderView::ResizeToContents );

‎src/gui/qgsbrowserdockwidget_p.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,9 @@ QgsBrowserTreeFilterProxyModel::QgsBrowserTreeFilterProxyModel( QObject *parent
339339
, mCaseSensitivity( Qt::CaseInsensitive )
340340
{
341341
setDynamicSortFilter( true );
342+
setSortRole( QgsBrowserModel::SortRole );
343+
setSortCaseSensitivity( Qt::CaseInsensitive );
344+
sort( 0 );
342345
}
343346

344347
void QgsBrowserTreeFilterProxyModel::setBrowserModel( QgsBrowserModel *model )

0 commit comments

Comments
 (0)
Please sign in to comment.