16 #include <QApplication> 
   18 #include <QtConcurrentMap> 
   31 #include "qgssettings.h" 
   37 #define PROJECT_HOME_PREFIX "project:" 
   38 #define HOME_PREFIX "home:" 
   41   : QFutureWatcher( nullptr )
 
   49   return QString::localeAwareCompare( a->
name(), b->
name() ) < 0;
 
   53   : QAbstractItemModel( parent )
 
   57            this, &QgsBrowserModel::dataItemProviderAdded );
 
   59            this, &QgsBrowserModel::dataItemProviderWillBeRemoved );
 
   78     beginRemoveRows( QModelIndex(), idx, idx );
 
   88     beginInsertRows( QModelIndex(), 0, 0 );
 
  101       QStringLiteral( 
"special:Home" ) );
 
  103   setupItemConnections( item );
 
  115   const auto drives { QDir::drives() };
 
  116   for ( 
const QFileInfo &drive : drives )
 
  118     const QString path = drive.absolutePath();
 
  124     item->
setSortKey( QStringLiteral( 
" 3 %1" ).arg( path ) );
 
  125     mDriveItems.insert( path, item );
 
  127     setupItemConnections( item );
 
  132   QString path = QString( 
"/Volumes" );
 
  134   setupItemConnections( vols );
 
  139   QMultiMap<int, QgsDataItem *> providerMap;
 
  144     if ( 
QgsDataItem *item = addProviderRootItem( pr ) )
 
  146       providerMap.insert( pr->capabilities(), item );
 
  151   const auto constUniqueKeys = providerMap.uniqueKeys();
 
  152   for ( 
int key : constUniqueKeys )
 
  154     QList<QgsDataItem *> providerGroup = providerMap.values( key );
 
  155     if ( providerGroup.size() > 1 )
 
  157       std::sort( providerGroup.begin(), providerGroup.end(), cmpByDataItemName_ );
 
  160     const auto constProviderGroup = providerGroup;
 
  185   if ( 
QgsDataItem *item = addProviderRootItem( provider ) )
 
  198     if ( item->providerKey() == provider->
name() )
 
  200       removeRootItem( item );
 
  206 void QgsBrowserModel::onConnectionsChanged( 
const QString &providerKey )
 
  211     if ( item->providerKey() == providerKey )
 
  229   if ( ! mInitialized )
 
  239   if ( !
index.isValid() )
 
  240     return Qt::ItemFlags();
 
  242   Qt::ItemFlags 
flags = Qt::ItemIsEnabled | Qt::ItemIsSelectable;
 
  249     return Qt::ItemFlags();
 
  253     flags |= Qt::ItemIsDragEnabled;
 
  257     flags |= Qt::ItemIsDropEnabled;
 
  261     flags |= Qt::ItemIsEditable;
 
  268   if ( !
index.isValid() )
 
  276   else if ( role == Qt::DisplayRole || role == Qt::EditRole )
 
  284   else if ( role == Qt::ToolTipRole )
 
  288   else if ( role == Qt::DecorationRole && 
index.column() == 0 )
 
  300       QgsLayerItem *lyrItem = qobject_cast<QgsLayerItem *>( item );
 
  318   if ( !
index.isValid() )
 
  336       return item->
rename( value.toString() );
 
  346   if ( orientation == Qt::Horizontal && role == Qt::DisplayRole )
 
  348     return QVariant( 
"header" );
 
  389   return findPath( 
this, path, matchFlag );
 
  395     return QModelIndex();
 
  398   bool foundChild = 
true;
 
  404     for ( 
int i = 0; i < model->rowCount( 
index ); i++ )
 
  406       QModelIndex idx = model->index( i, 0, 
index );
 
  408       QString itemPath = model->data( idx, 
PathRole ).toString();
 
  409       if ( itemPath == path )
 
  416       if ( path.startsWith( itemPath + 
'/' ) )
 
  425   if ( matchFlag == Qt::MatchStartsWith )
 
  429   return QModelIndex(); 
 
  434   for ( 
int i = 0; i < this->
rowCount( index ); i++ )
 
  438     if ( qobject_cast<QgsLayerItem *>( 
dataItem( idx ) ) )
 
  440       QString itemUri = qobject_cast<QgsLayerItem *>( 
dataItem( idx ) )->uri();
 
  442       if ( itemUri == uri )
 
  449     QModelIndex childIdx = 
findUri( uri, idx );
 
  450     if ( childIdx.isValid() )
 
  453   return QModelIndex();
 
  472   const QList< QFileInfo > drives = QDir::drives();
 
  474   const QStringList existingDrives = mDriveItems.keys();
 
  475   for ( 
const QString &drivePath : existingDrives )
 
  477     bool stillExists = 
false;
 
  478     for ( 
const QFileInfo &drive : drives )
 
  480       if ( drivePath == drive.absolutePath() )
 
  492       removeRootItem( driveItem );
 
  495   for ( 
const QFileInfo &drive : drives )
 
  497     const QString path = drive.absolutePath();
 
  503     if ( !mDriveItems.contains( path ) )
 
  506       item->
setSortKey( QStringLiteral( 
" 3 %1" ).arg( path ) );
 
  508       mDriveItems.insert( path, item );
 
  509       setupItemConnections( item );
 
  520   if ( column < 0 || column >= 
columnCount() || row < 0 )
 
  521     return QModelIndex();
 
  526   return item ? createIndex( row, column, item ) : QModelIndex();
 
  533     return QModelIndex();
 
  542   for ( 
int i = 0; i < items.size(); i++ )
 
  544     if ( items[i] == item )
 
  545       return createIndex( i, 0, item );
 
  547     QModelIndex childIndex = 
findItem( item, items[i] );
 
  548     if ( childIndex.isValid() )
 
  551   return QModelIndex();
 
  558   if ( !idx.isValid() )
 
  561   beginInsertRows( idx, first, last );
 
  573   if ( !idx.isValid() )
 
  575   beginRemoveRows( idx, first, last );
 
  586   if ( !idx.isValid() )
 
  588   emit dataChanged( idx, idx );
 
  595   if ( !idx.isValid() )
 
  597   QgsDebugMsgLevel( QStringLiteral( 
"item %1 state changed %2 -> %3" ).arg( item->
path() ).arg( qgsEnumValueToKey< Qgis::BrowserItemState >( oldState ) ).arg( qgsEnumValueToKey< Qgis::BrowserItemState >( item->
state() ) ), 4 );
 
  601 void QgsBrowserModel::setupItemConnections( 
QgsDataItem *item )
 
  618   if ( collectionItem )
 
  627   types << QStringLiteral( 
"application/x-vnd.qgis.qgis.uri" );
 
  634   const auto constIndexes = indexes;
 
  635   for ( 
const QModelIndex &
index : constIndexes )
 
  637     if ( 
index.isValid() )
 
  641       for ( 
const auto &uri : std::as_const( uris ) )
 
  666   void *v = idx.internalPointer();
 
  736   QgsSettings settings;
 
  737   QStringList hiddenItems = settings.value( QStringLiteral( 
"browser/hiddenPaths" ),
 
  738                             QStringList() ).toStringList();
 
  739   int idx = hiddenItems.indexOf( item->
path() );
 
  742     hiddenItems.removeAt( idx );
 
  746     hiddenItems << item->
path();
 
  748   settings.setValue( QStringLiteral( 
"browser/hiddenPaths" ), hiddenItems );
 
  755     removeRootItem( item );
 
  760 void QgsBrowserModel::removeRootItem( 
QgsDataItem *item )
 
  763   beginRemoveRows( QModelIndex(), i, i );
 
  766   if ( !mDriveItems.key( dirItem ).isEmpty() )
 
  768     mDriveItems.remove( mDriveItems.key( dirItem ) );
 
  791     setupItemConnections( item );
 
BrowserItemState
Browser item states.
@ NotPopulated
Children not yet created.
@ Populating
Creating children in separate thread (populating or refreshing)
@ Populated
Children created.
@ Rename
Item can be renamed.
@ Layer
Represents a map layer.
static QgsDataItemProviderRegistry * dataItemProviderRegistry()
Returns the application's data item provider registry, which keeps a list of data item providers that...
Q_DECL_DEPRECATED void connectItem(QgsDataItem *item)
void connectionsChanged(const QString &providerKey)
Emitted when connections for the specified providerKey have changed in the browser.
bool hasChildren(const QModelIndex &parent=QModelIndex()) const override
QgsFavoritesItem * mFavorites
QgsDataItem * dataItem(const QModelIndex &idx) const
Returns the data item at the specified index, or nullptr if no item exists at the index.
bool canFetchMore(const QModelIndex &parent) const override
void hidePath(QgsDataItem *item)
Hide the given path in the browser model.
void refreshDrives()
Refreshes the list of drive items, removing any corresponding to removed drives and adding newly adde...
void reload()
Reload the whole model.
Qt::ItemFlags flags(const QModelIndex &index) const override
void itemStateChanged(QgsDataItem *item, Qgis::BrowserItemState oldState)
Emitted when an item's state is changed.
void beginInsertItems(QgsDataItem *parent, int first, int last)
QModelIndex findPath(const QString &path, Qt::MatchFlag matchFlag=Qt::MatchExactly)
Returns index of item with given path.
QVariant headerData(int section, Qt::Orientation orientation, int role=Qt::DisplayRole) const override
void refresh(const QString &path)
Refresh item specified by path.
bool setData(const QModelIndex &index, const QVariant &value, int role=Qt::EditRole) override
int columnCount(const QModelIndex &parent=QModelIndex()) const override
QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const override
QVector< QgsDataItem * > mRootItems
QMap< QString, QgsDirectoryItem * > driveItems() const
Returns a map of the root drive items shown in the browser.
~QgsBrowserModel() override
int rowCount(const QModelIndex &parent=QModelIndex()) const override
void beginRemoveItems(QgsDataItem *parent, int first, int last)
QStringList mimeTypes() const override
QModelIndex parent(const QModelIndex &index) const override
QModelIndex findItem(QgsDataItem *item, QgsDataItem *parent=nullptr) const
Returns the model index corresponding to the specified data item.
void initialize()
Delayed initialization, needed because the provider registry must be already populated.
QMimeData * mimeData(const QModelIndexList &indexes) const override
void addFavoriteDirectory(const QString &directory, const QString &name=QString())
Adds a directory to the favorites group.
QgsBrowserModel(QObject *parent=nullptr)
Constructor for QgsBrowserModel, with the specified parent object.
QgsDirectoryItem * mProjectHome
QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const override
void stateChanged(const QModelIndex &index, Qgis::BrowserItemState oldState)
Emitted when item children fetch was finished.
void itemDataChanged(QgsDataItem *item)
void addRootItems()
Populates the model.
QModelIndex findUri(const QString &uri, QModelIndex index=QModelIndex())
Returns index of layer item with given uri.
@ CommentRole
Item comment.
@ ProviderKeyRole
Data item provider key that created the item, see QgsDataItem::providerKey()
@ PathRole
Item path used to access path in the tree, see QgsDataItem::mPath.
@ SortRole
Custom sort role, see QgsDataItem::sortKey()
bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) override
void removeFavorite(const QModelIndex &index)
Removes a favorite directory from its corresponding model index.
void fetchMore(const QModelIndex &parent) override
QgsBrowserWatcher(QgsDataItem *item)
A Collection: logical collection of layers or subcollections, e.g.
QList< QgsDataItemProvider * > providers() const
Returns the list of available providers.
void providerWillBeRemoved(QgsDataItemProvider *provider)
Emitted when a data item provider is about to be removed.
void providerAdded(QgsDataItemProvider *provider)
Emitted when a new data item provider has been added.
This is the interface for those who want to add custom data items to the browser tree.
virtual QgsDataItem * createDataItem(const QString &path, QgsDataItem *parentItem)=0
Create a new instance of QgsDataItem (or nullptr) for given path and parent item.
virtual int capabilities() const =0
Returns combination of flags from QgsDataProvider::DataCapabilities.
virtual QString name()=0
Human-readable name of the provider name.
Base class for all items in the model.
void stateChanged(QgsDataItem *item, Qgis::BrowserItemState oldState)
Emitted when an item's state is changed.
void setSortKey(const QVariant &key)
Sets a custom sorting key for the item.
virtual void deleteChildItem(QgsDataItem *child)
Removes and deletes a child item, emitting relevant signals to the model.
virtual QVariant sortKey() const
Returns the sorting key for the item.
virtual Q_DECL_DEPRECATED bool handleDrop(const QMimeData *, Qt::DropAction)
Attempts to process the mime data dropped on this item.
virtual void refresh(const QVector< QgsDataItem * > &children)
Refresh the items from a specified list of child items.
void dataChanged(QgsDataItem *item)
static void deleteLater(QVector< QgsDataItem * > &items)
QVector< QgsDataItem * > children() const
void beginRemoveItems(QgsDataItem *parent, int first, int last)
QgsDataItem * parent() const
Gets item parent.
virtual Q_DECL_DEPRECATED bool acceptDrop()
Returns whether the item accepts drag and dropped layers - e.g.
Qgis::BrowserItemType type() const
Qgis::BrowserItemState state() const
virtual bool hasDragEnabled() const
Returns true if the item may be dragged.
virtual Q_DECL_DEPRECATED bool rename(const QString &name)
Sets a new name for the item, and returns true if the item was successfully renamed.
void connectionsChanged(const QString &providerKey=QString())
Emitted when the connections of the provider with the specified providerKey have changed.
QString name() const
Returns the name of the item (the displayed text for the item).
void beginInsertItems(QgsDataItem *parent, int first, int last)
QString providerKey() const
Returns the provider key that created this item (e.g.
virtual Qgis::BrowserItemCapabilities capabilities2() const
Returns the capabilities for the data item.
void setProviderKey(const QString &value)
Sets the provider key that created this item (e.g.
virtual void populate(const QVector< QgsDataItem * > &children)
virtual QgsMimeDataUtils::UriList mimeUris() const
Returns mime URIs for the data item, most data providers will only return a single URI but some data ...
A directory: contains subdirectories and layers.
static bool hiddenPath(const QString &path)
Check if the given path is hidden from the browser model.
A directory item showing the a single favorite directory.
Contains various Favorites directories.
void addDirectory(const QString &directory, const QString &name=QString())
Adds a new directory to the favorites group.
void removeDirectory(QgsDirectoryItem *item)
Removes an existing directory from the favorites group.
Item that represents a layer that can be opened with one of the providers.
virtual QString comments() const
Returns comments of the layer.
QList< QgsMimeDataUtils::Uri > UriList
static QMimeData * encodeUriList(const UriList &layers)
Encodes a URI list to a new QMimeData object.
A directory item showing the current project directory.
static QgsProject * instance()
Returns the QgsProject singleton instance.
void homePathChanged()
Emitted when the home path of the project changes.
#define Q_NOWARN_DEPRECATED_POP
#define Q_NOWARN_DEPRECATED_PUSH
#define PROJECT_HOME_PREFIX
#define QgsDebugMsgLevel(str, level)