19#include "moc_qgsbrowsertreeview.cpp" 
   28#include <QSortFilterProxyModel> 
   31#include <QRegularExpression> 
   35  , mSettingsSection( QStringLiteral( 
"browser" ) )
 
   37  setEditTriggers( QAbstractItemView::EditKeyPressed );
 
 
   43  if ( event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter )
 
   44    emit doubleClicked( currentIndex() );
 
   46    QTreeView::keyPressEvent( event );
 
 
   51  QTreeView::setModel( model );
 
 
   58  mBrowserModel = model;
 
 
   66  QTreeView::showEvent( e );
 
 
   76  QTreeView::hideEvent( e );
 
 
   79void QgsBrowserTreeView::saveState()
 
   82  const QStringList expandedPaths = expandedPathsList( QModelIndex() );
 
   83  settings.
setValue( expandedPathsKey(), expandedPaths );
 
   87void QgsBrowserTreeView::restoreState()
 
   90  mExpandPaths = settings.
value( expandedPathsKey(), QVariant() ).toStringList();
 
   93  if ( !mExpandPaths.isEmpty() )
 
   95    QSet<QModelIndex> expandIndexSet;
 
   96    const auto constMExpandPaths = mExpandPaths;
 
   97    for ( 
const QString &path : constMExpandPaths )
 
  100      if ( expandIndex.isValid() )
 
  103        if ( modelIndex.isValid() )
 
  109            const QModelIndex parentIndex = model()->parent( expandIndex );
 
  111            if ( parentIndex.isValid() )
 
  112              expandIndexSet.insert( parentIndex );
 
  116            expandIndexSet.insert( expandIndex );
 
  125    const auto constExpandIndexSet = expandIndexSet;
 
  126    for ( 
const QModelIndex &expandIndex : constExpandIndexSet )
 
  128      expandTree( expandIndex );
 
  137void QgsBrowserTreeView::expandTree( 
const QModelIndex &index )
 
  145  const QModelIndex parentIndex = model()->parent( index );
 
  146  if ( parentIndex.isValid() )
 
  147    expandTree( parentIndex );
 
  150bool QgsBrowserTreeView::treeExpanded( 
const QModelIndex &index )
 
  154  if ( !isExpanded( index ) )
 
  156  const QModelIndex parentIndex = model()->parent( index );
 
  157  if ( parentIndex.isValid() )
 
  158    return treeExpanded( parentIndex );
 
  165  if ( !model() || !index.isValid() )
 
  168  for ( 
int i = 0; i < model()->rowCount( index ); i++ )
 
  170    const QModelIndex childIndex = model()->index( i, 0, index );
 
  171    if ( isExpanded( childIndex ) )
 
 
  183  if ( pathParts.isEmpty() )
 
  187  QVector<QgsDirectoryItem *> initialDirectoryItemCandidates;
 
  188  const QVector<QgsDataItem *> rootItems = mBrowserModel->
rootItems();
 
  193      initialDirectoryItemCandidates << dirItem;
 
  195    else if ( 
QgsFavoritesItem *favoritesItem = qobject_cast<QgsFavoritesItem *>( item ) )
 
  197      const QVector<QgsDataItem *> favoriteChildren = favoritesItem->children();
 
  198      for ( 
QgsDataItem *favoriteChild : favoriteChildren )
 
  200        if ( 
QgsDirectoryItem *dirItem = qobject_cast<QgsDirectoryItem *>( favoriteChild ) )
 
  202          initialDirectoryItemCandidates << dirItem;
 
  209  QString currentCandidatePath;
 
  210  for ( 
const QString &thisPart : pathParts )
 
  212    currentCandidatePath += ( currentCandidatePath.isEmpty() || currentCandidatePath.endsWith( 
'/' ) ? QString() : QStringLiteral( 
"/" ) ) + thisPart;
 
  214    auto it = initialDirectoryItemCandidates.begin();
 
  215    while ( it != initialDirectoryItemCandidates.end() )
 
  217      if ( !( *it )->dirPath().startsWith( currentCandidatePath ) )
 
  219        it = initialDirectoryItemCandidates.erase( it );
 
  223        if ( str.startsWith( ( *it )->dirPath() ) )
 
  224          currentDirectoryItem = *it;
 
  230  if ( !currentDirectoryItem )
 
  233  QStringList remainingParts = pathParts;
 
  234  auto it = remainingParts.begin();
 
  235  QDir currentDir = *it;
 
  236  while ( it != remainingParts.end() )
 
  238    if ( currentDirectoryItem->
dirPath().startsWith( currentDir.filePath( *it ) ) )
 
  240      currentDir = QDir( currentDir.filePath( *it ) );
 
  241      it = remainingParts.erase( it );
 
  249  currentDir = QDir( currentDirectoryItem->
dirPath() );
 
  250  QList<QgsDirectoryItem *> pathItems;
 
  252  pathItems << currentDirectoryItem;
 
  254  for ( 
const QString ¤tFolderName : std::as_const( remainingParts ) )
 
  256    const QString thisPath = currentDir.filePath( currentFolderName );
 
  258    if ( !QFile::exists( thisPath ) )
 
  263    const QVector<QgsDataItem *> children = currentDirectoryItem->
children();
 
  266      if ( 
QgsDirectoryItem *childDirectoryItem = qobject_cast<QgsDirectoryItem *>( child ) )
 
  268        if ( childDirectoryItem->dirPath() == thisPath )
 
  270          existingChild = childDirectoryItem;
 
  278      pathItems << existingChild;
 
  279      currentDirectoryItem = existingChild;
 
  286      currentDirectoryItem = newDir;
 
  289    currentDir = QDir( thisPath );
 
  295    QModelIndex index = mBrowserModel->
findItem( i );
 
  296    if ( QSortFilterProxyModel *proxyModel = qobject_cast<QSortFilterProxyModel *>( model() ) )
 
  298      index = proxyModel->mapFromSource( index );
 
  304  if ( selectPath && lastItem )
 
 
  310  if ( !mBrowserModel )
 
  313  QModelIndex index = mBrowserModel->
findItem( item );
 
  314  if ( !index.isValid() )
 
  317  if ( QSortFilterProxyModel *proxyModel = qobject_cast<QSortFilterProxyModel *>( model() ) )
 
  319    index = proxyModel->mapFromSource( index );
 
  322  setCurrentIndex( index );
 
 
  329  QTreeView::rowsInserted( parentIndex, start, end );
 
  334  if ( mExpandPaths.isEmpty() )
 
  343  mExpandPaths.removeOne( parentPath );
 
  346  if ( !treeExpanded( parentIndex ) )
 
  348    const auto constMExpandPaths = mExpandPaths;
 
  349    for ( 
const QString &path : constMExpandPaths )
 
  351      if ( path.startsWith( parentPath + 
'/' ) )
 
  352        mExpandPaths.removeOne( path );
 
  357  for ( 
int i = start; i <= end; i++ )
 
  359    const QModelIndex childIndex = model()->index( i, 0, parentIndex );
 
  361    const QString escapedChildPath = QRegularExpression::escape( childPath );
 
  363    QgsDebugMsgLevel( 
"childPath = " + childPath + 
" escapedChildPath = " + escapedChildPath, 2 );
 
  364    if ( mExpandPaths.contains( childPath ) || mExpandPaths.indexOf( QRegularExpression( 
"^" + escapedChildPath + 
"/.*" ) ) != -1 )
 
  368      if ( modelIndex.isValid() )
 
  373          expand( childIndex );
 
 
  380QString QgsBrowserTreeView::expandedPathsKey()
 const 
  382  return '/' + mSettingsSection + 
"/expandedPaths";
 
  385QStringList QgsBrowserTreeView::expandedPathsList( 
const QModelIndex &index )
 
  392  for ( 
int i = 0; i < model()->rowCount( index ); i++ )
 
  394    const QModelIndex childIndex = model()->index( i, 0, index );
 
  395    if ( isExpanded( childIndex ) )
 
  397      const QStringList childrenPaths = expandedPathsList( childIndex );
 
  398      if ( !childrenPaths.isEmpty() )
 
  400        paths.append( childrenPaths );
 
@ Collapse
The collapse/expand status for this items children should be ignored in order to avoid undesired netw...
 
A model for showing available data sources and other items in a structured tree.
 
QgsDataItem * dataItem(const QModelIndex &idx) const
Returns the data item at the specified index, or nullptr if no item exists at the index.
 
QModelIndex findPath(const QString &path, Qt::MatchFlag matchFlag=Qt::MatchExactly)
Returns index of item with given path.
 
QModelIndex findItem(QgsDataItem *item, QgsDataItem *parent=nullptr) const
Returns the model index corresponding to the specified data item.
 
QVector< QgsDataItem * > rootItems() const
Returns the root items for the model.
 
@ Path
Item path used to access path in the tree, see QgsDataItem::mPath.
 
void showEvent(QShowEvent *e) override
 
QgsBrowserTreeView(QWidget *parent=nullptr)
Constructor for QgsBrowserTreeView.
 
void keyPressEvent(QKeyEvent *event) override
 
void expandPath(const QString &path, bool selectPath=false)
Expands out a file path in the view.
 
void setBrowserModel(QgsBrowserGuiModel *model)
Sets the browser model.
 
void setModel(QAbstractItemModel *model) override
 
bool setSelectedItem(QgsDataItem *item)
Sets the item currently selected in the view.
 
void hideEvent(QHideEvent *e) override
 
bool hasExpandedDescendant(const QModelIndex &index) const
 
void rowsInserted(const QModelIndex &parentIndex, int start, int end) override
 
QgsBrowserGuiModel * browserModel()
Returns the browser model.
 
Base class for all items in the model.
 
QVector< QgsDataItem * > children() const
 
virtual void addChildItem(QgsDataItem *child, bool refresh=false)
Inserts a new child item.
 
virtual Qgis::BrowserItemCapabilities capabilities2() const
Returns the capabilities for the data item.
 
A browser item for directories: contains subdirectories and layers.
 
QString dirPath() const
Returns the full path to the directory the item represents.
 
A browser item which contains various Favorites directories.
 
static QStringList splitPathToComponents(const QString &path)
Given a file path, returns a list of all the components leading to that path.
 
Stores settings for use within QGIS.
 
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.
 
int scaleIconSize(int standardSize)
Scales an icon size to compensate for display pixel density, making the icon size hi-dpi friendly,...
 
#define QgsDebugMsgLevel(str, level)