16 #include <QApplication> 
   18 #include <QtConcurrentMap> 
   33 #define PROJECT_HOME_PREFIX "project:" 
   34 #define HOME_PREFIX "home:" 
   37   : QFutureWatcher( nullptr )
 
   45   return QString::localeAwareCompare( a->
name(), b->
name() ) < 0;
 
   49   : QAbstractItemModel( parent )
 
   53            this, &QgsBrowserModel::dataItemProviderAdded );
 
   55            this, &QgsBrowserModel::dataItemProviderWillBeRemoved );
 
   74     beginRemoveRows( QModelIndex(), idx, idx );
 
   84     beginInsertRows( QModelIndex(), 0, 0 );
 
   97       QStringLiteral( 
"special:Home" ) );
 
   99   setupItemConnections( item );
 
  111   const auto drives { QDir::drives() };
 
  112   for ( 
const QFileInfo &drive : drives )
 
  114     const QString path = drive.absolutePath();
 
  120     item->
setSortKey( QStringLiteral( 
" 3 %1" ).arg( path ) );
 
  121     mDriveItems.insert( path, item );
 
  123     setupItemConnections( item );
 
  128   QString path = QString( 
"/Volumes" );
 
  130   setupItemConnections( vols );
 
  135   QMultiMap<int, QgsDataItem *> providerMap;
 
  140     if ( 
QgsDataItem *item = addProviderRootItem( pr ) )
 
  142       providerMap.insert( pr->capabilities(), item );
 
  147   const auto constUniqueKeys = providerMap.uniqueKeys();
 
  148   for ( 
int key : constUniqueKeys )
 
  150     QList<QgsDataItem *> providerGroup = providerMap.values( key );
 
  151     if ( providerGroup.size() > 1 )
 
  153       std::sort( providerGroup.begin(), providerGroup.end(), cmpByDataItemName_ );
 
  156     const auto constProviderGroup = providerGroup;
 
  181   if ( 
QgsDataItem *item = addProviderRootItem( provider ) )
 
  194     if ( item->providerKey() == provider->
name() )
 
  196       removeRootItem( item );
 
  202 void QgsBrowserModel::onConnectionsChanged( 
const QString &providerKey )
 
  207     if ( item->providerKey() == providerKey )
 
  225   if ( ! mInitialized )
 
  235   if ( !
index.isValid() )
 
  236     return Qt::ItemFlags();
 
  238   Qt::ItemFlags 
flags = Qt::ItemIsEnabled | Qt::ItemIsSelectable;
 
  245     return Qt::ItemFlags();
 
  249     flags |= Qt::ItemIsDragEnabled;
 
  253     flags |= Qt::ItemIsDropEnabled;
 
  257     flags |= Qt::ItemIsEditable;
 
  264   if ( !
index.isValid() )
 
  272   else if ( role == Qt::DisplayRole || role == Qt::EditRole )
 
  280   else if ( role == Qt::ToolTipRole )
 
  284   else if ( role == Qt::DecorationRole && 
index.column() == 0 )
 
  296       QgsLayerItem *lyrItem = qobject_cast<QgsLayerItem *>( item );
 
  314   if ( !
index.isValid() )
 
  332       return item->
rename( value.toString() );
 
  342   if ( orientation == Qt::Horizontal && role == Qt::DisplayRole )
 
  344     return QVariant( 
"header" );
 
  385   return findPath( 
this, path, matchFlag );
 
  391     return QModelIndex();
 
  394   bool foundChild = 
true;
 
  400     for ( 
int i = 0; i < model->rowCount( 
index ); i++ )
 
  402       QModelIndex idx = model->index( i, 0, 
index );
 
  404       QString itemPath = model->data( idx, 
PathRole ).toString();
 
  405       if ( itemPath == path )
 
  412       if ( path.startsWith( itemPath + 
'/' ) )
 
  421   if ( matchFlag == Qt::MatchStartsWith )
 
  425   return QModelIndex(); 
 
  430   for ( 
int i = 0; i < this->
rowCount( index ); i++ )
 
  434     if ( qobject_cast<QgsLayerItem *>( 
dataItem( idx ) ) )
 
  436       QString itemUri = qobject_cast<QgsLayerItem *>( 
dataItem( idx ) )->uri();
 
  438       if ( itemUri == uri )
 
  445     QModelIndex childIdx = 
findUri( uri, idx );
 
  446     if ( childIdx.isValid() )
 
  449   return QModelIndex();
 
  468   const QList< QFileInfo > drives = QDir::drives();
 
  470   const QStringList existingDrives = mDriveItems.keys();
 
  471   for ( 
const QString &drivePath : existingDrives )
 
  473     bool stillExists = 
false;
 
  474     for ( 
const QFileInfo &drive : drives )
 
  476       if ( drivePath == drive.absolutePath() )
 
  488       removeRootItem( driveItem );
 
  491   for ( 
const QFileInfo &drive : drives )
 
  493     const QString path = drive.absolutePath();
 
  499     if ( !mDriveItems.contains( path ) )
 
  502       item->
setSortKey( QStringLiteral( 
" 3 %1" ).arg( path ) );
 
  504       mDriveItems.insert( path, item );
 
  505       setupItemConnections( item );
 
  516   if ( column < 0 || column >= 
columnCount() || row < 0 )
 
  517     return QModelIndex();
 
  522   return item ? createIndex( row, column, item ) : QModelIndex();
 
  529     return QModelIndex();
 
  538   for ( 
int i = 0; i < items.size(); i++ )
 
  540     if ( items[i] == item )
 
  541       return createIndex( i, 0, item );
 
  543     QModelIndex childIndex = 
findItem( item, items[i] );
 
  544     if ( childIndex.isValid() )
 
  547   return QModelIndex();
 
  554   if ( !idx.isValid() )
 
  557   beginInsertRows( idx, first, last );
 
  569   if ( !idx.isValid() )
 
  571   beginRemoveRows( idx, first, last );
 
  582   if ( !idx.isValid() )
 
  584   emit dataChanged( idx, idx );
 
  591   if ( !idx.isValid() )
 
  593   QgsDebugMsgLevel( QStringLiteral( 
"item %1 state changed %2 -> %3" ).arg( item->
path() ).arg( oldState ).arg( item->
state() ), 4 );
 
  597 void QgsBrowserModel::setupItemConnections( 
QgsDataItem *item )
 
  614   if ( collectionItem )
 
  623   types << QStringLiteral( 
"application/x-vnd.qgis.qgis.uri" );
 
  630   const auto constIndexes = indexes;
 
  631   for ( 
const QModelIndex &
index : constIndexes )
 
  633     if ( 
index.isValid() )
 
  637       for ( 
const auto &uri : qgis::as_const( uris ) )
 
  662   void *v = idx.internalPointer();
 
  733   QStringList hiddenItems = settings.
value( QStringLiteral( 
"browser/hiddenPaths" ),
 
  734                             QStringList() ).toStringList();
 
  735   int idx = hiddenItems.indexOf( item->
path() );
 
  738     hiddenItems.removeAt( idx );
 
  742     hiddenItems << item->
path();
 
  744   settings.
setValue( QStringLiteral( 
"browser/hiddenPaths" ), hiddenItems );
 
  751     removeRootItem( item );
 
  756 void QgsBrowserModel::removeRootItem( 
QgsDataItem *item )
 
  759   beginRemoveRows( QModelIndex(), i, i );
 
  762   if ( !mDriveItems.key( dirItem ).isEmpty() )
 
  764     mDriveItems.remove( mDriveItems.key( dirItem ) );
 
  787     setupItemConnections( item );
 
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 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.
void stateChanged(const QModelIndex &index, QgsDataItem::State oldState)
Emitted when item children fetch was finished.
~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.
void itemStateChanged(QgsDataItem *item, QgsDataItem::State oldState)
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 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 setSortKey(const QVariant &key)
Sets a custom sorting key for the item.
virtual Capabilities capabilities2() const
Returns the capabilities for the data item.
virtual void deleteChildItem(QgsDataItem *child)
Removes and deletes a child item, emitting relevant signals to the model.
@ Populated
Children created.
@ Populating
Creating children in separate thread (populating or refreshing)
@ NotPopulated
Children not yet created.
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
@ Rename
Item can be renamed.
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.
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)
void stateChanged(QgsDataItem *item, QgsDataItem::State oldState)
QString providerKey() const
Returns the provider key that created this item (e.g.
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.
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.
static QgsProject * instance()
Returns the QgsProject singleton instance.
void homePathChanged()
Emitted when the home path of the project changes.
This class is a composition of two QSettings instances:
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
void setValue(const QString &key, const QVariant &value, QgsSettings::Section section=QgsSettings::NoSection)
Sets the value of setting key to value.
#define Q_NOWARN_DEPRECATED_POP
#define Q_NOWARN_DEPRECATED_PUSH
#define PROJECT_HOME_PREFIX
#define QgsDebugMsgLevel(str, level)