mirror of
https://github.com/qgis/QGIS.git
synced 2025-10-15 00:02:52 -04:00
[FEATURE] Allow customization of the items shown in browser (#33679)
* [FEATURE] Allow customization of the items show is browser. User can select in Interface Customization dialog to hide some of the items in the browser panel Funded by Limerick City and County Council
This commit is contained in:
parent
a9ed83f1a6
commit
ecd90c6ecb
@ -55,6 +55,7 @@ Constructor for QgsBrowserModel, with the specified ``parent`` object.
|
||||
PathRole,
|
||||
CommentRole,
|
||||
SortRole,
|
||||
ProviderKeyRole,
|
||||
};
|
||||
|
||||
virtual Qt::ItemFlags flags( const QModelIndex &index ) const;
|
||||
@ -161,7 +162,6 @@ and on Linux the "/" root directory.
|
||||
|
||||
.. versionadded:: 3.6
|
||||
%End
|
||||
|
||||
signals:
|
||||
|
||||
void stateChanged( const QModelIndex &index, QgsDataItem::State oldState );
|
||||
@ -232,7 +232,6 @@ Delayed initialization, needed because the provider registry must be already pop
|
||||
.. seealso:: :py:func:`initialized`
|
||||
%End
|
||||
|
||||
|
||||
protected:
|
||||
void addRootItems();
|
||||
%Docstring
|
||||
|
@ -131,6 +131,21 @@ filterByLayerType() is ``True``.
|
||||
.. seealso:: :py:func:`layerType`
|
||||
|
||||
.. seealso:: :py:func:`setFilterByLayerType`
|
||||
%End
|
||||
|
||||
void setDataItemProviderKeyFilter( const QStringList &filter );
|
||||
%Docstring
|
||||
Sets the customization filters for data items based on item's data provider key
|
||||
|
||||
By default browser model shows all items from all available data items provider and few special
|
||||
items (e.g. Favourites). To customize the behavious, set the filter to not load certain data items.
|
||||
The items that are not based on data item providers have prefix "special:", for example
|
||||
"special:Favourites", "special:Home", "PostGIS", "MSSQL"
|
||||
|
||||
All items created by the providers listed in filter are hidden from the layer tree.
|
||||
This filter is always evaluated.
|
||||
|
||||
.. versionadded:: 3.12
|
||||
%End
|
||||
|
||||
protected:
|
||||
|
@ -52,9 +52,10 @@ Parent/children hierarchy is not based on QObject.
|
||||
};
|
||||
|
||||
|
||||
QgsDataItem( QgsDataItem::Type type, QgsDataItem *parent /TransferThis/, const QString &name, const QString &path );
|
||||
QgsDataItem( QgsDataItem::Type type, QgsDataItem *parent /TransferThis/, const QString &name, const QString &path, const QString &providerKey = QString() );
|
||||
%Docstring
|
||||
Create new data item.
|
||||
Creates new data item
|
||||
``providerKey`` added in QGIS 3.12
|
||||
%End
|
||||
~QgsDataItem();
|
||||
|
||||
@ -300,6 +301,27 @@ Sets the ``name`` of the item (the displayed text for the item).
|
||||
|
||||
QString path() const;
|
||||
void setPath( const QString &path );
|
||||
|
||||
QString providerKey() const;
|
||||
%Docstring
|
||||
Returns the provider key that created this item (e.g. "PostGIS")
|
||||
|
||||
If key has a prefix "special:", it marks that the item was not created with a provider,
|
||||
but manually. For example "special:Favorites", "special:Home"
|
||||
|
||||
.. versionadded:: 3.12
|
||||
%End
|
||||
|
||||
void setProviderKey( const QString &value );
|
||||
%Docstring
|
||||
Sets the provider key that created this item (e.g. "PostGIS")
|
||||
|
||||
If key has a prefix "special:", it marks that the item was not created with a provider,
|
||||
but manually. For example "special:Favorites"
|
||||
|
||||
.. versionadded:: 3.12
|
||||
%End
|
||||
|
||||
static QString pathComponent( const QString &component );
|
||||
%Docstring
|
||||
Create path component replacing path separators
|
||||
@ -525,7 +547,6 @@ Use QgsDataItemGuiProvider.deleteLayer instead
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
public:
|
||||
static QIcon iconPoint();
|
||||
static QIcon iconLine();
|
||||
@ -556,7 +577,10 @@ A Collection: logical collection of layers or subcollections, e.g. GRASS locatio
|
||||
#include "qgsdataitem.h"
|
||||
%End
|
||||
public:
|
||||
QgsDataCollectionItem( QgsDataItem *parent, const QString &name, const QString &path = QString() );
|
||||
QgsDataCollectionItem( QgsDataItem *parent, const QString &name, const QString &path = QString(), const QString &providerKey = QString() );
|
||||
%Docstring
|
||||
Constructor
|
||||
%End
|
||||
~QgsDataCollectionItem();
|
||||
|
||||
void addChild( QgsDataItem *item /Transfer/ );
|
||||
@ -605,14 +629,15 @@ A directory: contains subdirectories and layers
|
||||
|
||||
QgsDirectoryItem( QgsDataItem *parent, const QString &name, const QString &path );
|
||||
|
||||
QgsDirectoryItem( QgsDataItem *parent, const QString &name, const QString &dirPath, const QString &path );
|
||||
QgsDirectoryItem( QgsDataItem *parent, const QString &name, const QString &dirPath, const QString &path, const QString &providerKey = QString() );
|
||||
%Docstring
|
||||
Constructor.
|
||||
|
||||
:param parent:
|
||||
:param name: directory name
|
||||
:param dirPath: path to directory in file system
|
||||
:param path: item path in the tree, it may be dirPath or dirPath with some prefix, e.g. favorites: *
|
||||
:param path: item path in the tree, it may be dirPath or dirPath with some prefix, e.g. favorites:
|
||||
:param providerKey: key of the provider that created this item
|
||||
%End
|
||||
|
||||
virtual void setState( State state );
|
||||
@ -662,13 +687,14 @@ Data item that can be used to represent QGIS projects.
|
||||
%End
|
||||
public:
|
||||
|
||||
QgsProjectItem( QgsDataItem *parent, const QString &name, const QString &path );
|
||||
QgsProjectItem( QgsDataItem *parent, const QString &name, const QString &path, const QString &providerKey = QString() );
|
||||
%Docstring
|
||||
A data item holding a reference to a QGIS project file.
|
||||
|
||||
:param parent: The parent data item.
|
||||
:param name: The name of the of the project. Displayed to the user.
|
||||
:param path: The full path to the project.
|
||||
:param providerKey: key of the provider that created this item
|
||||
%End
|
||||
|
||||
virtual bool hasDragEnabled() const;
|
||||
@ -782,7 +808,14 @@ A zip file: contains layers, using GDAL/OGR VSIFILE mechanism
|
||||
|
||||
public:
|
||||
QgsZipItem( QgsDataItem *parent, const QString &name, const QString &path );
|
||||
QgsZipItem( QgsDataItem *parent, const QString &name, const QString &filePath, const QString &path );
|
||||
%Docstring
|
||||
Constructor
|
||||
%End
|
||||
|
||||
QgsZipItem( QgsDataItem *parent, const QString &name, const QString &filePath, const QString &path, const QString &providerKey = QString() );
|
||||
%Docstring
|
||||
Constructor
|
||||
%End
|
||||
|
||||
virtual QVector<QgsDataItem *> createChildren();
|
||||
|
||||
|
@ -58,6 +58,20 @@ Returns the message bar associated with the dock.
|
||||
.. seealso:: :py:func:`setMessageBar`
|
||||
|
||||
.. versionadded:: 3.6
|
||||
%End
|
||||
|
||||
void setDisabledDataItemsKeys( const QStringList &filter );
|
||||
%Docstring
|
||||
Sets the customization for data items based on item's data provider key
|
||||
|
||||
By default browser model shows all items from all available data items provider and few special
|
||||
items (e.g. Favourites). To customize the behavior, set the filter to not load certain data items.
|
||||
The items that are not based on data item providers (e.g. Favourites, Home) have
|
||||
prefix "special:"
|
||||
|
||||
Used in the proxy browser model to hide items
|
||||
|
||||
.. versionadded:: 3.12
|
||||
%End
|
||||
|
||||
public slots:
|
||||
@ -190,8 +204,6 @@ Show event override
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
/************************************************************************
|
||||
* This file has been generated automatically from *
|
||||
* *
|
||||
|
@ -1300,6 +1300,10 @@ QgisApp::QgisApp( QSplashScreen *splash, bool restorePlugins, bool skipVersionCh
|
||||
|
||||
QgsApplication::dataItemProviderRegistry()->addProvider( new QgsProjectDataItemProvider() );
|
||||
|
||||
// now when all data item providers are registered, customize both browsers
|
||||
QgsCustomization::instance()->updateBrowserWidget( mBrowserWidget );
|
||||
QgsCustomization::instance()->updateBrowserWidget( mBrowserWidget2 );
|
||||
|
||||
// Create the plugin registry and load plugins
|
||||
// load any plugins that were running in the last session
|
||||
mSplash->showMessage( tr( "Restoring loaded plugins" ), Qt::AlignHCenter | Qt::AlignBottom );
|
||||
|
@ -19,6 +19,9 @@
|
||||
#include "qgsapplication.h"
|
||||
#include "qgslogger.h"
|
||||
#include "qgsstatusbar.h"
|
||||
#include "qgsbrowserdockwidget.h"
|
||||
#include "qgsdataitemprovider.h"
|
||||
#include "qgsdataitemproviderregistry.h"
|
||||
#include "qgsgui.h"
|
||||
|
||||
#include <QAction>
|
||||
@ -359,6 +362,7 @@ void QgsCustomizationDialog::init()
|
||||
}
|
||||
|
||||
treeWidget->insertTopLevelItems( 0, QgsCustomization::instance()->mMainWindowItems );
|
||||
treeWidget->addTopLevelItem( QgsCustomization::instance()->mBrowserItem );
|
||||
|
||||
for ( int i = 0; i < treeWidget->topLevelItemCount(); i++ )
|
||||
treeWidget->expandItem( treeWidget->topLevelItem( i ) );
|
||||
@ -696,6 +700,42 @@ void QgsCustomization::createTreeItemStatus()
|
||||
mMainWindowItems << topItem;
|
||||
}
|
||||
|
||||
void QgsCustomization::createTreeItemBrowser()
|
||||
{
|
||||
if ( mBrowserItem )
|
||||
return;
|
||||
|
||||
QStringList data;
|
||||
data << QStringLiteral( "Browser" );
|
||||
mBrowserItem = new QTreeWidgetItem( data );
|
||||
QVector<QStringList> items;
|
||||
|
||||
items << QStringList( {QStringLiteral( "special:Home" ), tr( "Home Folder" )} );
|
||||
items << QStringList( {QStringLiteral( "special:ProjectHome" ), tr( "Project tHome Folder" )} );
|
||||
items << QStringList( {QStringLiteral( "special:Favorites" ), tr( "Favorites Folder" )} );
|
||||
items << QStringList( {QStringLiteral( "special:Drives" ), tr( "Drive Folders (e.g. C:\\)" )} );
|
||||
items << QStringList( {QStringLiteral( "special:Volumes" ), tr( "Volume Folder (MacOS only)" )} );
|
||||
|
||||
const auto constProviders = QgsApplication::dataItemProviderRegistry()->providers();
|
||||
for ( QgsDataItemProvider *pr : constProviders )
|
||||
{
|
||||
int capabilities = pr->capabilities();
|
||||
if ( capabilities != QgsDataProvider::NoDataCapabilities )
|
||||
{
|
||||
QStringList item;
|
||||
item << QStringLiteral( "%1" ).arg( pr->name() ) << QObject::tr( "Data Item Provider: %1" ).arg( pr->name() );
|
||||
items << item;
|
||||
}
|
||||
}
|
||||
|
||||
for ( const QStringList &strs : items )
|
||||
{
|
||||
QTreeWidgetItem *item = new QTreeWidgetItem( mBrowserItem, strs );
|
||||
item->setFlags( Qt::ItemIsEnabled | Qt::ItemIsUserCheckable | Qt::ItemIsSelectable );
|
||||
item->setCheckState( 0, Qt::Checked );
|
||||
}
|
||||
}
|
||||
|
||||
QgsCustomization *QgsCustomization::sInstance = nullptr;
|
||||
QgsCustomization *QgsCustomization::instance()
|
||||
{
|
||||
@ -975,6 +1015,34 @@ void QgsCustomization::removeFromLayout( QLayout *layout, QWidget *widget )
|
||||
}
|
||||
}
|
||||
|
||||
void QgsCustomization::updateBrowserWidget( QgsBrowserDockWidget *widget )
|
||||
{
|
||||
createTreeItemBrowser();
|
||||
|
||||
if ( !widget )
|
||||
return;
|
||||
|
||||
if ( !mEnabled )
|
||||
return;
|
||||
|
||||
if ( !mBrowserItem )
|
||||
return;
|
||||
|
||||
QStringList disabledDataItems;
|
||||
mSettings->beginGroup( QStringLiteral( "Customization/Browser" ) );
|
||||
for ( int i = 0; i < mBrowserItem->childCount(); ++i )
|
||||
{
|
||||
const QTreeWidgetItem *item = mBrowserItem->child( i );
|
||||
if ( item && !mSettings->value( item->text( 0 ), true ).toBool() )
|
||||
{
|
||||
disabledDataItems << item->text( 0 );
|
||||
}
|
||||
}
|
||||
mSettings->endGroup();
|
||||
|
||||
widget->setDisabledDataItemsKeys( disabledDataItems );
|
||||
}
|
||||
|
||||
void QgsCustomization::preNotify( QObject *receiver, QEvent *event, bool *done )
|
||||
{
|
||||
if ( event->type() == QEvent::Show || event->type() == QEvent::MouseButtonPress )
|
||||
|
@ -31,6 +31,7 @@ class QTreeWidgetItem;
|
||||
class QEvent;
|
||||
class QMouseEvent;
|
||||
class QSettings;
|
||||
class QgsBrowserDockWidget;
|
||||
|
||||
class APP_EXPORT QgsCustomizationDialog : public QMainWindow, private Ui::QgsCustomizationDialogBase
|
||||
{
|
||||
@ -129,6 +130,7 @@ class APP_EXPORT QgsCustomization : public QObject
|
||||
static void customizeWidget( const QString &path, QWidget *widget, QSettings *settings );
|
||||
static void removeFromLayout( QLayout *layout, QWidget *widget );
|
||||
|
||||
void updateBrowserWidget( QgsBrowserDockWidget *model );
|
||||
void updateMainWindow( QMenu *toolBarMenu );
|
||||
|
||||
// make sure to enable/disable before creating QgisApp in order to get it customized (or not)
|
||||
@ -162,10 +164,12 @@ class APP_EXPORT QgsCustomization : public QObject
|
||||
void createTreeItemToolbars();
|
||||
void createTreeItemDocks();
|
||||
void createTreeItemStatus();
|
||||
void createTreeItemBrowser();
|
||||
void addTreeItemMenu( QTreeWidgetItem *parentItem, const QMenu *menu, const QAction *action = nullptr );
|
||||
void addTreeItemActions( QTreeWidgetItem *parentItem, const QList<QAction *> &actions );
|
||||
QList<QTreeWidgetItem *> mMainWindowItems;
|
||||
friend class QgsCustomizationDialog; // in order to access mMainWindowItems
|
||||
QTreeWidgetItem *mBrowserItem = nullptr;
|
||||
friend class QgsCustomizationDialog; // in order to access mMainWindowItems and mBrowserItem
|
||||
|
||||
private:
|
||||
static QgsCustomization *sInstance;
|
||||
|
@ -88,7 +88,9 @@ void QgsBrowserModel::addRootItems()
|
||||
updateProjectHome();
|
||||
|
||||
// give the home directory a prominent third place
|
||||
QgsDirectoryItem *item = new QgsDirectoryItem( nullptr, tr( "Home" ), QDir::homePath(), QStringLiteral( HOME_PREFIX ) + QDir::homePath() );
|
||||
QgsDirectoryItem *item = new QgsDirectoryItem( nullptr, tr( "Home" ), QDir::homePath(),
|
||||
QStringLiteral( HOME_PREFIX ) + QDir::homePath(),
|
||||
QStringLiteral( "special:Home" ) );
|
||||
item->setSortKey( QStringLiteral( " 2" ) );
|
||||
setupItemConnections( item );
|
||||
mRootItems << item;
|
||||
@ -110,7 +112,7 @@ void QgsBrowserModel::addRootItems()
|
||||
if ( QgsDirectoryItem::hiddenPath( path ) )
|
||||
continue;
|
||||
|
||||
QgsDirectoryItem *item = new QgsDirectoryItem( nullptr, path, path );
|
||||
QgsDirectoryItem *item = new QgsDirectoryItem( nullptr, path, QString(), path, QStringLiteral( "special:Drives" ) );
|
||||
item->setSortKey( QStringLiteral( " 3 %1" ).arg( path ) );
|
||||
mDriveItems.insert( path, item );
|
||||
|
||||
@ -120,7 +122,7 @@ void QgsBrowserModel::addRootItems()
|
||||
|
||||
#ifdef Q_OS_MAC
|
||||
QString path = QString( "/Volumes" );
|
||||
QgsDirectoryItem *vols = new QgsDirectoryItem( nullptr, path, path );
|
||||
QgsDirectoryItem *vols = new QgsDirectoryItem( nullptr, path, QString(), path, QStringLiteral( "special:Volumes" ) );
|
||||
mRootItems << vols;
|
||||
#endif
|
||||
|
||||
@ -140,6 +142,8 @@ void QgsBrowserModel::addRootItems()
|
||||
QgsDataItem *item = pr->createDataItem( QString(), nullptr ); // empty path -> top level
|
||||
if ( item )
|
||||
{
|
||||
// make sure the top level key is set always
|
||||
item->setProviderKey( pr->name() );
|
||||
// Forward the signal from the root items to the model (and then to the app)
|
||||
connect( item, &QgsDataItem::connectionsChanged, this, &QgsBrowserModel::connectionsChanged );
|
||||
QgsDebugMsgLevel( "Add new top level item : " + item->name(), 4 );
|
||||
@ -194,7 +198,6 @@ void QgsBrowserModel::initialize()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Qt::ItemFlags QgsBrowserModel::flags( const QModelIndex &index ) const
|
||||
{
|
||||
if ( !index.isValid() )
|
||||
@ -263,6 +266,10 @@ QVariant QgsBrowserModel::data( const QModelIndex &index, int role ) const
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
else if ( role == QgsBrowserModel::ProviderKeyRole )
|
||||
{
|
||||
return item->providerKey();
|
||||
}
|
||||
else
|
||||
{
|
||||
// unsupported role
|
||||
|
@ -90,6 +90,7 @@ class CORE_EXPORT QgsBrowserModel : public QAbstractItemModel
|
||||
PathRole = Qt::UserRole, //!< Item path used to access path in the tree, see QgsDataItem::mPath
|
||||
CommentRole = Qt::UserRole + 1, //!< Item comment
|
||||
SortRole, //!< Custom sort role, see QgsDataItem::sortKey()
|
||||
ProviderKeyRole, //!< Data item provider key that created the item, \since QGIS 3.12
|
||||
};
|
||||
// implemented methods from QAbstractItemModel for read-only access
|
||||
|
||||
@ -175,7 +176,6 @@ class CORE_EXPORT QgsBrowserModel : public QAbstractItemModel
|
||||
* \since QGIS 3.6
|
||||
*/
|
||||
QMap<QString, QgsDirectoryItem *> driveItems() const;
|
||||
|
||||
signals:
|
||||
|
||||
//! Emitted when item children fetch was finished
|
||||
@ -243,7 +243,6 @@ class CORE_EXPORT QgsBrowserModel : public QAbstractItemModel
|
||||
*/
|
||||
void initialize();
|
||||
|
||||
|
||||
protected:
|
||||
//! Populates the model
|
||||
void addRootItems();
|
||||
|
@ -146,10 +146,13 @@ bool QgsBrowserProxyModel::filterAcceptsString( const QString &value ) const
|
||||
|
||||
bool QgsBrowserProxyModel::filterAcceptsRow( int sourceRow, const QModelIndex &sourceParent ) const
|
||||
{
|
||||
if ( ( mFilter.isEmpty() && !mFilterByLayerType ) || !mModel )
|
||||
if ( ( mFilter.isEmpty() && !mFilterByLayerType && mHiddenDataItemsKeys.empty() ) || !mModel )
|
||||
return true;
|
||||
|
||||
QModelIndex sourceIndex = mModel->index( sourceRow, 0, sourceParent );
|
||||
if ( !filterAcceptsProviderKey( sourceIndex ) || !filterRootAcceptsProviderKey( sourceIndex ) )
|
||||
return false;
|
||||
|
||||
return filterAcceptsItem( sourceIndex ) || filterAcceptsAncestor( sourceIndex ) || filterAcceptsDescendant( sourceIndex );
|
||||
}
|
||||
|
||||
@ -230,3 +233,35 @@ bool QgsBrowserProxyModel::filterAcceptsItem( const QModelIndex &sourceIndex ) c
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool QgsBrowserProxyModel::filterAcceptsProviderKey( const QModelIndex &sourceIndex ) const
|
||||
{
|
||||
if ( !mModel )
|
||||
return true;
|
||||
|
||||
const QString providerKey = mModel->data( sourceIndex, QgsBrowserModel::ProviderKeyRole ).toString();
|
||||
if ( providerKey.isEmpty() )
|
||||
return true;
|
||||
|
||||
return !mHiddenDataItemsKeys.contains( providerKey );
|
||||
}
|
||||
|
||||
bool QgsBrowserProxyModel::filterRootAcceptsProviderKey( const QModelIndex &sourceIndex ) const
|
||||
{
|
||||
if ( !mModel )
|
||||
return true;
|
||||
|
||||
QModelIndex sourceParentIndex = mModel->parent( sourceIndex );
|
||||
if ( !sourceParentIndex.isValid() )
|
||||
{
|
||||
return filterAcceptsProviderKey( sourceIndex );
|
||||
}
|
||||
|
||||
return filterRootAcceptsProviderKey( sourceParentIndex );
|
||||
}
|
||||
|
||||
void QgsBrowserProxyModel::setDataItemProviderKeyFilter( const QStringList &filter )
|
||||
{
|
||||
mHiddenDataItemsKeys = filter;
|
||||
invalidateFilter();
|
||||
}
|
||||
|
@ -143,13 +143,28 @@ class CORE_EXPORT QgsBrowserProxyModel : public QSortFilterProxyModel
|
||||
*/
|
||||
void setLayerType( QgsMapLayerType type );
|
||||
|
||||
/**
|
||||
* Sets the customization filters for data items based on item's data provider key
|
||||
*
|
||||
* By default browser model shows all items from all available data items provider and few special
|
||||
* items (e.g. Favourites). To customize the behavious, set the filter to not load certain data items.
|
||||
* The items that are not based on data item providers have prefix "special:", for example
|
||||
* "special:Favourites", "special:Home", "PostGIS", "MSSQL"
|
||||
*
|
||||
* All items created by the providers listed in filter are hidden from the layer tree.
|
||||
* This filter is always evaluated.
|
||||
*
|
||||
* \since QGIS 3.12
|
||||
*/
|
||||
void setDataItemProviderKeyFilter( const QStringList &filter );
|
||||
|
||||
protected:
|
||||
|
||||
// It would be better to apply the filer only to expanded (visible) items, but using mapFromSource() + view here was causing strange errors
|
||||
bool filterAcceptsRow( int sourceRow, const QModelIndex &sourceParent ) const override;
|
||||
|
||||
private:
|
||||
|
||||
QStringList mHiddenDataItemsKeys;
|
||||
QgsBrowserModel *mModel = nullptr;
|
||||
QString mFilter; //filter string provided
|
||||
QVector<QRegExp> mREList; //list of filters, separated by "|"
|
||||
@ -173,6 +188,12 @@ class CORE_EXPORT QgsBrowserProxyModel : public QSortFilterProxyModel
|
||||
|
||||
//! Filter accepts item name
|
||||
bool filterAcceptsItem( const QModelIndex &sourceIndex ) const;
|
||||
|
||||
//! Filter accepts provider key.
|
||||
bool filterAcceptsProviderKey( const QModelIndex &sourceIndex ) const;
|
||||
|
||||
//! Root item accepts provider key.
|
||||
bool filterRootAcceptsProviderKey( const QModelIndex &sourceIndex ) const;
|
||||
};
|
||||
|
||||
#endif // QGSBROWSERPROXYMODEL_H
|
||||
|
@ -121,13 +121,14 @@ QIcon QgsZipItem::iconZip()
|
||||
|
||||
QgsAnimatedIcon *QgsDataItem::sPopulatingIcon = nullptr;
|
||||
|
||||
QgsDataItem::QgsDataItem( QgsDataItem::Type type, QgsDataItem *parent, const QString &name, const QString &path )
|
||||
QgsDataItem::QgsDataItem( QgsDataItem::Type type, QgsDataItem *parent, const QString &name, const QString &path, const QString &providerKey )
|
||||
// Do not pass parent to QObject, Qt would delete this when parent is deleted
|
||||
: mType( type )
|
||||
, mCapabilities( NoCapabilities )
|
||||
, mParent( parent )
|
||||
, mState( NotPopulated )
|
||||
, mName( name )
|
||||
, mProviderKey( providerKey )
|
||||
, mPath( path )
|
||||
, mDeferredDelete( false )
|
||||
, mFutureWatcher( nullptr )
|
||||
@ -438,6 +439,16 @@ void QgsDataItem::refresh( const QVector<QgsDataItem *> &children )
|
||||
setState( Populated );
|
||||
}
|
||||
|
||||
QString QgsDataItem::providerKey() const
|
||||
{
|
||||
return mProviderKey;
|
||||
}
|
||||
|
||||
void QgsDataItem::setProviderKey( const QString &value )
|
||||
{
|
||||
mProviderKey = value;
|
||||
}
|
||||
|
||||
int QgsDataItem::rowCount()
|
||||
{
|
||||
return mChildren.size();
|
||||
@ -607,9 +618,9 @@ QList<QMenu *> QgsDataItem::menus( QWidget *parent )
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
QgsLayerItem::QgsLayerItem( QgsDataItem *parent, const QString &name, const QString &path, const QString &uri, LayerType layerType, const QString &providerKey )
|
||||
: QgsDataItem( Layer, parent, name, path )
|
||||
, mProviderKey( providerKey )
|
||||
QgsLayerItem::QgsLayerItem( QgsDataItem *parent, const QString &name, const QString &path,
|
||||
const QString &uri, LayerType layerType, const QString &providerKey )
|
||||
: QgsDataItem( Layer, parent, name, path, providerKey )
|
||||
, mUri( uri )
|
||||
, mLayerType( layerType )
|
||||
{
|
||||
@ -784,8 +795,11 @@ QgsMimeDataUtils::Uri QgsLayerItem::mimeUri() const
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
QgsDataCollectionItem::QgsDataCollectionItem( QgsDataItem *parent, const QString &name, const QString &path )
|
||||
: QgsDataItem( Collection, parent, name, path )
|
||||
QgsDataCollectionItem::QgsDataCollectionItem( QgsDataItem *parent,
|
||||
const QString &name,
|
||||
const QString &path,
|
||||
const QString &providerKey )
|
||||
: QgsDataItem( Collection, parent, name, path, providerKey )
|
||||
{
|
||||
mCapabilities = Fertile;
|
||||
mIconName = QStringLiteral( "/mIconDbSchema.svg" );
|
||||
@ -817,8 +831,10 @@ QgsDirectoryItem::QgsDirectoryItem( QgsDataItem *parent, const QString &name, co
|
||||
init();
|
||||
}
|
||||
|
||||
QgsDirectoryItem::QgsDirectoryItem( QgsDataItem *parent, const QString &name, const QString &dirPath, const QString &path )
|
||||
: QgsDataCollectionItem( parent, QDir::toNativeSeparators( name ), path )
|
||||
QgsDirectoryItem::QgsDirectoryItem( QgsDataItem *parent, const QString &name,
|
||||
const QString &dirPath, const QString &path,
|
||||
const QString &providerKey )
|
||||
: QgsDataCollectionItem( parent, QDir::toNativeSeparators( name ), path, providerKey )
|
||||
, mDirPath( dirPath )
|
||||
, mRefreshLater( false )
|
||||
{
|
||||
@ -1207,8 +1223,9 @@ void QgsDirectoryParamWidget::showHideColumn()
|
||||
settings.setValue( QStringLiteral( "dataitem/directoryHiddenColumns" ), lst );
|
||||
}
|
||||
|
||||
QgsProjectItem::QgsProjectItem( QgsDataItem *parent, const QString &name, const QString &path )
|
||||
: QgsDataItem( QgsDataItem::Project, parent, name, path )
|
||||
QgsProjectItem::QgsProjectItem( QgsDataItem *parent, const QString &name,
|
||||
const QString &path, const QString &providerKey )
|
||||
: QgsDataItem( QgsDataItem::Project, parent, name, path, providerKey )
|
||||
{
|
||||
mIconName = QStringLiteral( ":/images/icons/qgis_icon.svg" );
|
||||
setToolTip( QDir::toNativeSeparators( path ) );
|
||||
@ -1233,7 +1250,7 @@ QgsErrorItem::QgsErrorItem( QgsDataItem *parent, const QString &error, const QSt
|
||||
}
|
||||
|
||||
QgsFavoritesItem::QgsFavoritesItem( QgsDataItem *parent, const QString &name, const QString &path )
|
||||
: QgsDataCollectionItem( parent, name, QStringLiteral( "favorites:" ) )
|
||||
: QgsDataCollectionItem( parent, name, QStringLiteral( "favorites:" ), QStringLiteral( "special:Favorites" ) )
|
||||
{
|
||||
Q_UNUSED( path )
|
||||
mCapabilities |= Fast;
|
||||
@ -1392,8 +1409,10 @@ QgsZipItem::QgsZipItem( QgsDataItem *parent, const QString &name, const QString
|
||||
init();
|
||||
}
|
||||
|
||||
QgsZipItem::QgsZipItem( QgsDataItem *parent, const QString &name, const QString &filePath, const QString &path )
|
||||
: QgsDataCollectionItem( parent, name, path )
|
||||
QgsZipItem::QgsZipItem( QgsDataItem *parent, const QString &name,
|
||||
const QString &filePath, const QString &path,
|
||||
const QString &providerKey )
|
||||
: QgsDataCollectionItem( parent, name, path, providerKey )
|
||||
, mFilePath( filePath )
|
||||
{
|
||||
init();
|
||||
@ -1584,7 +1603,7 @@ QStringList QgsZipItem::getZipFileList()
|
||||
///@cond PRIVATE
|
||||
|
||||
QgsProjectHomeItem::QgsProjectHomeItem( QgsDataItem *parent, const QString &name, const QString &dirPath, const QString &path )
|
||||
: QgsDirectoryItem( parent, name, dirPath, path )
|
||||
: QgsDirectoryItem( parent, name, dirPath, path, QStringLiteral( "special:ProjectHome" ) )
|
||||
{
|
||||
}
|
||||
|
||||
@ -1602,7 +1621,7 @@ QVariant QgsProjectHomeItem::sortKey() const
|
||||
|
||||
|
||||
QgsFavoriteItem::QgsFavoriteItem( QgsFavoritesItem *parent, const QString &name, const QString &dirPath, const QString &path )
|
||||
: QgsDirectoryItem( parent, name, dirPath, path )
|
||||
: QgsDirectoryItem( parent, name, dirPath, path, QStringLiteral( "special:Favorites" ) )
|
||||
, mFavorites( parent )
|
||||
{
|
||||
mCapabilities |= Rename;
|
||||
|
@ -86,8 +86,11 @@ class CORE_EXPORT QgsDataItem : public QObject
|
||||
|
||||
Q_ENUM( Type )
|
||||
|
||||
//! Create new data item.
|
||||
QgsDataItem( QgsDataItem::Type type, QgsDataItem *parent SIP_TRANSFERTHIS, const QString &name, const QString &path );
|
||||
/**
|
||||
* Creates new data item
|
||||
* \a providerKey added in QGIS 3.12
|
||||
*/
|
||||
QgsDataItem( QgsDataItem::Type type, QgsDataItem *parent SIP_TRANSFERTHIS, const QString &name, const QString &path, const QString &providerKey = QString() );
|
||||
~QgsDataItem() override;
|
||||
|
||||
bool hasChildren();
|
||||
@ -308,6 +311,27 @@ class CORE_EXPORT QgsDataItem : public QObject
|
||||
|
||||
QString path() const { return mPath; }
|
||||
void setPath( const QString &path ) { mPath = path; }
|
||||
|
||||
/**
|
||||
* Returns the provider key that created this item (e.g. "PostGIS")
|
||||
*
|
||||
* If key has a prefix "special:", it marks that the item was not created with a provider,
|
||||
* but manually. For example "special:Favorites", "special:Home"
|
||||
*
|
||||
* \since QGIS 3.12
|
||||
*/
|
||||
QString providerKey() const;
|
||||
|
||||
/**
|
||||
* Sets the provider key that created this item (e.g. "PostGIS")
|
||||
*
|
||||
* If key has a prefix "special:", it marks that the item was not created with a provider,
|
||||
* but manually. For example "special:Favorites"
|
||||
*
|
||||
* \since QGIS 3.12
|
||||
*/
|
||||
void setProviderKey( const QString &value );
|
||||
|
||||
//! Create path component replacing path separators
|
||||
static QString pathComponent( const QString &component );
|
||||
|
||||
@ -369,6 +393,7 @@ class CORE_EXPORT QgsDataItem : public QObject
|
||||
QVector<QgsDataItem *> mChildren; // easier to have it always
|
||||
State mState;
|
||||
QString mName;
|
||||
QString mProviderKey;
|
||||
// Path is slash ('/') separated chain of item identifiers which are usually item names, but may be different if it is
|
||||
// necessary to distinguish paths of two providers to the same source (e.g GRASS location and standard directory have the same
|
||||
// name but different paths). Identifiers in path must not contain '/' characters.
|
||||
@ -537,9 +562,6 @@ class CORE_EXPORT QgsLayerItem : public QgsDataItem
|
||||
Q_DECL_DEPRECATED virtual bool deleteLayer() SIP_DEPRECATED;
|
||||
|
||||
protected:
|
||||
|
||||
//! The provider key
|
||||
QString mProviderKey;
|
||||
//! The URI
|
||||
QString mUri;
|
||||
//! The layer type
|
||||
@ -572,7 +594,8 @@ class CORE_EXPORT QgsDataCollectionItem : public QgsDataItem
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QgsDataCollectionItem( QgsDataItem *parent, const QString &name, const QString &path = QString() );
|
||||
//! Constructor
|
||||
QgsDataCollectionItem( QgsDataItem *parent, const QString &name, const QString &path = QString(), const QString &providerKey = QString() );
|
||||
~QgsDataCollectionItem() override;
|
||||
|
||||
void addChild( QgsDataItem *item SIP_TRANSFER ) { mChildren.append( item ); }
|
||||
@ -620,8 +643,10 @@ class CORE_EXPORT QgsDirectoryItem : public QgsDataCollectionItem
|
||||
* \param parent
|
||||
* \param name directory name
|
||||
* \param dirPath path to directory in file system
|
||||
* \param path item path in the tree, it may be dirPath or dirPath with some prefix, e.g. favorites: */
|
||||
QgsDirectoryItem( QgsDataItem *parent, const QString &name, const QString &dirPath, const QString &path );
|
||||
* \param path item path in the tree, it may be dirPath or dirPath with some prefix, e.g. favorites:
|
||||
* \param providerKey key of the provider that created this item
|
||||
*/
|
||||
QgsDirectoryItem( QgsDataItem *parent, const QString &name, const QString &dirPath, const QString &path, const QString &providerKey = QString() );
|
||||
|
||||
void setState( State state ) override;
|
||||
|
||||
@ -669,8 +694,9 @@ class CORE_EXPORT QgsProjectItem : public QgsDataItem
|
||||
* \param parent The parent data item.
|
||||
* \param name The name of the of the project. Displayed to the user.
|
||||
* \param path The full path to the project.
|
||||
* \param providerKey key of the provider that created this item
|
||||
*/
|
||||
QgsProjectItem( QgsDataItem *parent, const QString &name, const QString &path );
|
||||
QgsProjectItem( QgsDataItem *parent, const QString &name, const QString &path, const QString &providerKey = QString() );
|
||||
|
||||
bool hasDragEnabled() const override { return true; }
|
||||
|
||||
@ -775,8 +801,11 @@ class CORE_EXPORT QgsZipItem : public QgsDataCollectionItem
|
||||
QStringList mZipFileList;
|
||||
|
||||
public:
|
||||
//! Constructor
|
||||
QgsZipItem( QgsDataItem *parent, const QString &name, const QString &path );
|
||||
QgsZipItem( QgsDataItem *parent, const QString &name, const QString &filePath, const QString &path );
|
||||
|
||||
//! Constructor
|
||||
QgsZipItem( QgsDataItem *parent, const QString &name, const QString &filePath, const QString &path, const QString &providerKey = QString() );
|
||||
|
||||
QVector<QgsDataItem *> createChildren() override;
|
||||
QStringList getZipFileList();
|
||||
|
@ -128,6 +128,7 @@ void QgsBrowserDockWidget::showEvent( QShowEvent *e )
|
||||
{
|
||||
mProxyModel = new QgsBrowserProxyModel( this );
|
||||
mProxyModel->setBrowserModel( mModel );
|
||||
mProxyModel->setDataItemProviderKeyFilter( mDisabledDataItemsKeys );
|
||||
mBrowserView->setSettingsSection( objectName().toLower() ); // to distinguish 2 or more instances of the browser
|
||||
mBrowserView->setBrowserModel( mModel );
|
||||
mBrowserView->setModel( mProxyModel );
|
||||
@ -289,6 +290,16 @@ QgsMessageBar *QgsBrowserDockWidget::messageBar()
|
||||
return mMessageBar;
|
||||
}
|
||||
|
||||
void QgsBrowserDockWidget::setDisabledDataItemsKeys( const QStringList &filter )
|
||||
{
|
||||
mDisabledDataItemsKeys = filter;
|
||||
|
||||
if ( !mProxyModel )
|
||||
return;
|
||||
|
||||
mProxyModel->setDataItemProviderKeyFilter( mDisabledDataItemsKeys );
|
||||
}
|
||||
|
||||
void QgsBrowserDockWidget::removeFavorite()
|
||||
{
|
||||
mModel->removeFavorite( mProxyModel->mapToSource( mBrowserView->currentIndex() ) );
|
||||
|
@ -80,6 +80,20 @@ class GUI_EXPORT QgsBrowserDockWidget : public QgsDockWidget, private Ui::QgsBro
|
||||
*/
|
||||
QgsMessageBar *messageBar();
|
||||
|
||||
/**
|
||||
* Sets the customization for data items based on item's data provider key
|
||||
*
|
||||
* By default browser model shows all items from all available data items provider and few special
|
||||
* items (e.g. Favourites). To customize the behavior, set the filter to not load certain data items.
|
||||
* The items that are not based on data item providers (e.g. Favourites, Home) have
|
||||
* prefix "special:"
|
||||
*
|
||||
* Used in the proxy browser model to hide items
|
||||
*
|
||||
* \since QGIS 3.12
|
||||
*/
|
||||
void setDisabledDataItemsKeys( const QStringList &filter );
|
||||
|
||||
public slots:
|
||||
|
||||
/**
|
||||
@ -192,9 +206,7 @@ class GUI_EXPORT QgsBrowserDockWidget : public QgsDockWidget, private Ui::QgsBro
|
||||
float mPropertiesWidgetHeight;
|
||||
|
||||
QgsMessageBar *mMessageBar = nullptr;
|
||||
|
||||
QStringList mDisabledDataItemsKeys;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif // QGSBROWSERDOCKWIDGET_H
|
||||
|
@ -75,7 +75,7 @@ void TestQgsBrowserModel::testModel()
|
||||
QVERIFY( !model.dataItem( QModelIndex() ) );
|
||||
|
||||
// add a root child
|
||||
QgsDataCollectionItem *rootItem1 = new QgsDataCollectionItem( nullptr, QStringLiteral( "Test" ), QStringLiteral( "root1" ) );
|
||||
QgsDataCollectionItem *rootItem1 = new QgsDataCollectionItem( nullptr, QStringLiteral( "Test" ), QStringLiteral( "root1" ), QStringLiteral( "providerKeyRoot1" ) );
|
||||
QVERIFY( !model.findItem( rootItem1 ).isValid() );
|
||||
model.setupItemConnections( rootItem1 );
|
||||
model.mRootItems.append( rootItem1 );
|
||||
@ -95,6 +95,7 @@ void TestQgsBrowserModel::testModel()
|
||||
QVERIFY( !model.hasChildren( root1Index ) );
|
||||
QCOMPARE( model.data( root1Index ).toString(), QStringLiteral( "Test" ) );
|
||||
QCOMPARE( model.data( root1Index, QgsBrowserModel::PathRole ).toString(), QStringLiteral( "root1" ) );
|
||||
QCOMPARE( model.data( root1Index, QgsBrowserModel::ProviderKeyRole ).toString(), QStringLiteral( "providerKeyRoot1" ) );
|
||||
QCOMPARE( model.dataItem( root1Index ), rootItem1 );
|
||||
QCOMPARE( model.findItem( rootItem1 ), root1Index );
|
||||
|
||||
@ -111,11 +112,12 @@ void TestQgsBrowserModel::testModel()
|
||||
QCOMPARE( model.columnCount( root2Index ), 1 );
|
||||
QCOMPARE( model.data( root2Index ).toString(), QStringLiteral( "Test2" ) );
|
||||
QCOMPARE( model.data( root2Index, QgsBrowserModel::PathRole ).toString(), QStringLiteral( "root2" ) );
|
||||
QVERIFY( model.data( root2Index, QgsBrowserModel::ProviderKeyRole ).toString().isEmpty() );
|
||||
QCOMPARE( model.dataItem( root2Index ), rootItem2 );
|
||||
QCOMPARE( model.findItem( rootItem2 ), root2Index );
|
||||
|
||||
// child item
|
||||
QgsDataCollectionItem *childItem1 = new QgsDataCollectionItem( nullptr, QStringLiteral( "Child1" ), QStringLiteral( "child1" ) );
|
||||
QgsDataCollectionItem *childItem1 = new QgsDataCollectionItem( nullptr, QStringLiteral( "Child1" ), QStringLiteral( "child1" ), QStringLiteral( "providerKeyChild1" ) );
|
||||
model.setupItemConnections( childItem1 );
|
||||
rootItem1->addChild( childItem1 );
|
||||
|
||||
@ -127,6 +129,7 @@ void TestQgsBrowserModel::testModel()
|
||||
QModelIndex child1Index = model.index( 0, 0, root1Index );
|
||||
QCOMPARE( model.data( child1Index ).toString(), QStringLiteral( "Child1" ) );
|
||||
QCOMPARE( model.data( child1Index, QgsBrowserModel::PathRole ).toString(), QStringLiteral( "child1" ) );
|
||||
QCOMPARE( model.data( child1Index, QgsBrowserModel::ProviderKeyRole ).toString(), QStringLiteral( "providerKeyChild1" ) );
|
||||
QCOMPARE( model.dataItem( child1Index ), childItem1 );
|
||||
QCOMPARE( model.findItem( childItem1 ), child1Index );
|
||||
QCOMPARE( model.findItem( childItem1, rootItem1 ), child1Index );
|
||||
|
@ -99,7 +99,7 @@ void TestQgsBrowserProxyModel::testModel()
|
||||
QCOMPARE( proxy.dataItem( root1Index ), rootItem1 );
|
||||
|
||||
// second root item
|
||||
QgsDataCollectionItem *rootItem2 = new QgsDataCollectionItem( nullptr, QStringLiteral( "Test2" ), QStringLiteral( "root2" ) );
|
||||
QgsDataCollectionItem *rootItem2 = new QgsDataCollectionItem( nullptr, QStringLiteral( "Test2" ), QStringLiteral( "root2" ), QStringLiteral( "provider2" ) );
|
||||
model.setupItemConnections( rootItem2 );
|
||||
model.beginInsertRows( QModelIndex(), 1, 1 );
|
||||
model.mRootItems.append( rootItem2 );
|
||||
@ -116,7 +116,7 @@ void TestQgsBrowserProxyModel::testModel()
|
||||
QCOMPARE( proxy.dataItem( root2Index ), rootItem2 );
|
||||
|
||||
// child item
|
||||
QgsDataCollectionItem *childItem1 = new QgsDataCollectionItem( nullptr, QStringLiteral( "Child1" ), QStringLiteral( "child1" ) );
|
||||
QgsDataCollectionItem *childItem1 = new QgsDataCollectionItem( nullptr, QStringLiteral( "Child1" ), QStringLiteral( "child1" ), QStringLiteral( "provider1" ) );
|
||||
rootItem1->addChildItem( childItem1, true );
|
||||
|
||||
QCOMPARE( proxy.rowCount(), 2 );
|
||||
@ -250,6 +250,20 @@ void TestQgsBrowserProxyModel::testModel()
|
||||
QCOMPARE( proxy.rowCount( child2Index ), 0 );
|
||||
QCOMPARE( proxy.rowCount( root2Index ), 1 );
|
||||
QCOMPARE( proxy.data( proxy.index( 0, 0, root2Index ) ).toString(), QStringLiteral( "Child4" ) );
|
||||
|
||||
proxy.setFilterByLayerType( false );
|
||||
|
||||
// provider filtering
|
||||
proxy.setDataItemProviderKeyFilter( QStringList( {QStringLiteral( "provider1" )} ) );
|
||||
QCOMPARE( proxy.rowCount(), 2 );
|
||||
root1Index = proxy.index( 0, 0 );
|
||||
QCOMPARE( proxy.rowCount( root1Index ), 1 );
|
||||
proxy.setDataItemProviderKeyFilter( QStringList( {QStringLiteral( "provider2" )} ) );
|
||||
QCOMPARE( proxy.rowCount(), 1 );
|
||||
root1Index = proxy.index( 0, 0 );
|
||||
QCOMPARE( proxy.rowCount( root1Index ), 2 );
|
||||
proxy.setDataItemProviderKeyFilter( QStringList() );
|
||||
QCOMPARE( proxy.rowCount(), 2 );
|
||||
}
|
||||
|
||||
QGSTEST_MAIN( TestQgsBrowserProxyModel )
|
||||
|
Loading…
x
Reference in New Issue
Block a user