19#include "moc_qgsdirectoryitem.cpp" 
   28#include <QFileSystemWatcher> 
   47                                    const QString &dirPath, 
const QString &path,
 
   48                                    const QString &providerKey )
 
 
   55void QgsDirectoryItem::init( 
const QString &dirName )
 
   64  mIsSymLink = fi.isSymLink();
 
   67  switch ( mMonitoring )
 
   80  settings.
beginGroup( QStringLiteral( 
"qgis/browserPathColors" ) );
 
   82  settingKey.replace( 
'/', QLatin1String( 
"|||" ) );
 
   83  if ( settings.
childKeys().contains( settingKey ) )
 
   85    const QString colorString = settings.
value( settingKey ).toString();
 
   86    mIconColor = QColor( colorString );
 
   91  setSortKey( QStringLiteral( 
"  %1" ).arg( dirName ) );
 
   97  switch ( mMonitoring )
 
  110  const QVector<QgsDataItem *> childItems = 
children();
 
  113    if ( 
QgsDirectoryItem *dirItem = qobject_cast< QgsDirectoryItem *>( child ) )
 
  114      dirItem->reevaluateMonitoring();
 
  117  createOrDestroyFileSystemWatcher();
 
 
  120void QgsDirectoryItem::createOrDestroyFileSystemWatcher()
 
  122  if ( !mMonitored && mFileSystemWatcher )
 
  124    mFileSystemWatcher->deleteLater();
 
  125    mFileSystemWatcher = 
nullptr;
 
  129    mFileSystemWatcher = 
new QFileSystemWatcher( 
this );
 
  130    mFileSystemWatcher->addPath( 
mDirPath );
 
  142  if ( color == mIconColor )
 
 
  152  settings.
beginGroup( QStringLiteral( 
"qgis/browserPathColors" ) );
 
  153  QString settingKey = directory;
 
  154  settingKey.replace( 
'/', QLatin1String( 
"|||" ) );
 
  155  if ( color.isValid() )
 
  156    settings.
setValue( settingKey, color.name( QColor::HexArgb ) );
 
  158    settings.
remove( settingKey );
 
 
  165    return homeDirIcon( mIconColor, mIconColor.darker() );
 
  172  if ( mIsDir && mIsSymLink )
 
  174    return mIconColor.isValid()
 
  181    return openDirIcon( mIconColor, mIconColor.darker() );
 
  184  return iconDir( mIconColor, mIconColor.darker() );
 
 
  197  QStringList noMonitorDirs = settings.
value( QStringLiteral( 
"qgis/disableMonitorItemUris" ), QStringList() ).toStringList();
 
  198  QStringList alwaysMonitorDirs = settings.
value( QStringLiteral( 
"qgis/alwaysMonitorItemUris" ), QStringList() ).toStringList();
 
  200  switch ( mMonitoring )
 
  205      noMonitorDirs.removeAll( 
mDirPath );
 
  206      settings.
setValue( QStringLiteral( 
"qgis/disableMonitorItemUris" ), noMonitorDirs );
 
  208      alwaysMonitorDirs.removeAll( 
mDirPath );
 
  209      settings.
setValue( QStringLiteral( 
"qgis/alwaysMonitorItemUris" ), alwaysMonitorDirs );
 
  217      if ( !noMonitorDirs.contains( 
mDirPath ) )
 
  220        settings.
setValue( QStringLiteral( 
"qgis/disableMonitorItemUris" ), noMonitorDirs );
 
  223      alwaysMonitorDirs.removeAll( 
mDirPath );
 
  224      settings.
setValue( QStringLiteral( 
"qgis/alwaysMonitorItemUris" ), alwaysMonitorDirs );
 
  232      noMonitorDirs.removeAll( 
mDirPath );
 
  233      settings.
setValue( QStringLiteral( 
"qgis/disableMonitorItemUris" ), noMonitorDirs );
 
  235      if ( !alwaysMonitorDirs.contains( 
mDirPath ) )
 
  237        alwaysMonitorDirs.append( 
mDirPath );
 
  238        settings.
setValue( QStringLiteral( 
"qgis/alwaysMonitorItemUris" ), alwaysMonitorDirs );
 
  246  const QVector<QgsDataItem *> childItems = 
children();
 
  249    if ( 
QgsDirectoryItem *dirItem = qobject_cast< QgsDirectoryItem *>( child ) )
 
  250      dirItem->reevaluateMonitoring();
 
  253  createOrDestroyFileSystemWatcher();
 
 
  263  const QStringList entries = dir.entryList( QDir::AllDirs | QDir::NoDotAndDotDot, QDir::Name | QDir::IgnoreCase );
 
  264  for ( 
const QString &subdir : entries )
 
  272    const QString subdirPath = dir.absoluteFilePath( subdir );
 
  274    QgsDebugMsgLevel( QStringLiteral( 
"creating subdir: %1" ).arg( subdirPath ), 2 );
 
  276    const QString 
path = 
mPath + ( 
mPath.endsWith( 
'/' ) ? QString() : QStringLiteral( 
"/" ) ) + subdir; 
 
  280    bool handledByProvider = 
false;
 
  283      if ( provider->handlesDirectoryPath( subdirPath ) )
 
  285        handledByProvider = 
true;
 
  289    if ( handledByProvider )
 
  299  const QStringList fileEntries = dir.entryList( QDir::Dirs | QDir::NoDotAndDotDot | QDir::Files, QDir::Name );
 
  300  for ( 
const QString &
name : fileEntries )
 
  308    const QString 
path = dir.absoluteFilePath( 
name );
 
  309    const QFileInfo fileInfo( 
path );
 
  320    bool createdItem = 
false;
 
  348      if ( fileInfo.suffix().compare( QLatin1String( 
"qgs" ), Qt::CaseInsensitive ) == 0 ||
 
  349           fileInfo.suffix().compare( QLatin1String( 
"qgz" ), Qt::CaseInsensitive ) == 0 )
 
 
  368    if ( !mFileSystemWatcher )
 
  370      mFileSystemWatcher = 
new QFileSystemWatcher( 
this );
 
  371      mFileSystemWatcher->addPath( 
mDirPath );
 
  374    mLastScan = QDateTime::currentDateTime();
 
  378    if ( mFileSystemWatcher )
 
  380      delete mFileSystemWatcher;
 
  381      mFileSystemWatcher = 
nullptr;
 
 
  389  if ( mLastScan.msecsTo( QDateTime::currentDateTime() ) < 
QgsSettings().value( QStringLiteral( 
"browser/minscaninterval" ), 10000 ).toInt() )
 
  396    mRefreshLater = 
true;
 
  410    QTimer::singleShot( 100, 
this, [
this] { 
refresh(); } );
 
 
  417  const QStringList hiddenItems = settings.
value( QStringLiteral( 
"browser/hiddenPaths" ),
 
  418                                  QStringList() ).toStringList();
 
  419  const int idx = hiddenItems.indexOf( 
path );
 
 
  426  if ( settings.
value( QStringLiteral( 
"qgis/disableMonitorItemUris" ), QStringList() ).toStringList().contains( 
path ) )
 
  428  else if ( settings.
value( QStringLiteral( 
"qgis/alwaysMonitorItemUris" ), QStringList() ).toStringList().contains( 
path ) )
 
 
  437  const QString originalPath = QDir::cleanPath( 
path );
 
  438  QString currentPath = originalPath;
 
  440  while ( currentPath != prevPath )
 
  442    prevPath = currentPath;
 
  443    currentPath = QFileInfo( currentPath ).path();
 
  465  return QgsSettings().
value( QStringLiteral( 
"/qgis/monitorDirectoriesInBrowser" ), 
true ).toBool();
 
 
  470  QgsDebugMsgLevel( QStringLiteral( 
"mRefreshLater = %1" ).arg( mRefreshLater ), 3 );
 
  474    QgsDebugMsgLevel( QStringLiteral( 
"directory changed during createChildren() -> refresh() again" ), 3 );
 
  475    mRefreshLater = 
false;
 
  484  if ( mFileSystemWatcher && mMonitored )
 
 
  495  const QgsDirectoryItem *otherDirItem = qobject_cast< const QgsDirectoryItem * >( other );
 
 
  510  u.
layerType = QStringLiteral( 
"directory" );
 
 
  521  : QTreeWidget( parent )
 
  523  setRootIsDecorated( 
false );
 
  528  labels << tr( 
"Name" ) << tr( 
"Size" ) << tr( 
"Date" ) << tr( 
"Permissions" ) << tr( 
"Owner" ) << tr( 
"Group" ) << tr( 
"Type" );
 
  529  setHeaderLabels( labels );
 
  536  QList<QTreeWidgetItem *> items;
 
  538  const QDir dir( path );
 
  539  const QStringList entries = dir.entryList( QDir::AllEntries | QDir::NoDotAndDotDot, QDir::Name | QDir::IgnoreCase );
 
  540  for ( 
const QString &name : entries )
 
  542    const QFileInfo fi( dir.absoluteFilePath( name ) );
 
  546    if ( fi.size() > 1024 )
 
  548      size = QStringLiteral( 
"%1 KiB" ).arg( QLocale().toString( fi.size() / 1024.0, 
'f', 1 ) );
 
  550    else if ( fi.size() > 1.048576e6 )
 
  552      size = QStringLiteral( 
"%1 MiB" ).arg( QLocale().toString( fi.size() / 1.048576e6, 
'f', 1 ) );
 
  556      size = QStringLiteral( 
"%1 B" ).arg( fi.size() );
 
  559    texts << QLocale().toString( fi.lastModified(), QLocale::ShortFormat );
 
  561    perm += fi.permission( QFile::ReadOwner ) ? 
'r' : 
'-';
 
  562    perm += fi.permission( QFile::WriteOwner ) ? 
'w' : 
'-';
 
  563    perm += fi.permission( QFile::ExeOwner ) ? 
'x' : 
'-';
 
  565    perm += fi.permission( QFile::ReadGroup ) ? 
'r' : 
'-';
 
  566    perm += fi.permission( QFile::WriteGroup ) ? 
'w' : 
'-';
 
  567    perm += fi.permission( QFile::ExeGroup ) ? 
'x' : 
'-';
 
  568    perm += fi.permission( QFile::ReadOther ) ? 
'r' : 
'-';
 
  569    perm += fi.permission( QFile::WriteOther ) ? 
'w' : 
'-';
 
  570    perm += fi.permission( QFile::ExeOther ) ? 
'x' : 
'-';
 
  578    if ( fi.isDir() && fi.isSymLink() )
 
  580      type = tr( 
"folder" );
 
  583    else if ( fi.isDir() )
 
  585      type = tr( 
"folder" );
 
  586      icon = iconDirectory;
 
  588    else if ( fi.isFile() && fi.isSymLink() )
 
  593    else if ( fi.isFile() )
 
  601    QTreeWidgetItem *item = 
new QTreeWidgetItem( texts );
 
  602    item->setIcon( 0, icon );
 
  606  addTopLevelItems( items );
 
  610  const QList<QVariant> lst = settings.
value( QStringLiteral( 
"dataitem/directoryHiddenColumns" ) ).toList();
 
  611  for ( 
const QVariant &colVariant : lst )
 
  613    setColumnHidden( colVariant.toInt(), 
true );
 
 
  619  if ( event->button() == Qt::RightButton )
 
  625    labels << tr( 
"Name" ) << tr( 
"Size" ) << tr( 
"Date" ) << tr( 
"Permissions" ) << tr( 
"Owner" ) << tr( 
"Group" ) << tr( 
"Type" );
 
  626    for ( 
int i = 0; i < labels.count(); i++ )
 
  629      action->setObjectName( QString::number( i ) );
 
  630      action->setCheckable( 
true );
 
  631      action->setChecked( !isColumnHidden( i ) );
 
  634    popupMenu.exec( event->globalPos() );
 
 
  640  QAction *action = qobject_cast<QAction *>( sender() );
 
  644  const int columnIndex = action->objectName().toInt();
 
  645  setColumnHidden( columnIndex, !isColumnHidden( columnIndex ) );
 
  650  for ( 
int i = 0; i < columnCount(); i++ )
 
  652    if ( isColumnHidden( i ) )
 
  653      lst.append( QVariant( i ) );
 
  655  settings.
setValue( QStringLiteral( 
"dataitem/directoryHiddenColumns" ), lst );
 
 
  663  : 
QgsDirectoryItem( parent, name, dirPath, path, QStringLiteral( 
"special:ProjectHome" ) )
 
 
  676  return QStringLiteral( 
" 1" );
 
 
@ Files
Can provides items which corresponds to files.
 
@ Directories
Can provides items which corresponds to directories.
 
BrowserItemState
Browser item states.
 
@ NotPopulated
Children not yet created.
 
@ Populating
Creating children in separate thread (populating or refreshing)
 
@ Populated
Children created.
 
@ ItemRepresentsFile
Item's path() directly represents a file on disk.
 
BrowserDirectoryMonitoring
Browser directory item monitoring switches.
 
@ Default
Use default logic to determine whether directory should be monitored.
 
@ AlwaysMonitor
Always monitor the directory, regardless of the default logic.
 
@ NeverMonitor
Never monitor the directory, regardless of the default logic.
 
QFlags< DataItemProviderCapability > DataItemProviderCapabilities
Capabilities for data item providers.
 
@ Directory
Represents a file directory.
 
static QgsDataItemProviderRegistry * dataItemProviderRegistry()
Returns the application's data item provider registry, which keeps a list of data item providers that...
 
static QIcon getThemeIcon(const QString &name, const QColor &fillColor=QColor(), const QColor &strokeColor=QColor())
Helper to get a theme icon.
 
A browser item for collections of data.
 
static QIcon homeDirIcon(const QColor &fillColor=QColor(), const QColor &strokeColor=QColor())
Shared home directory icon.
 
static QIcon iconDir(const QColor &fillColor=QColor(), const QColor &strokeColor=QColor())
Returns the standard browser directory icon.
 
static QIcon openDirIcon(const QColor &fillColor=QColor(), const QColor &strokeColor=QColor())
Shared open directory icon.
 
QList< QgsDataItemProvider * > providers() const
Returns the list of available providers.
 
Interface for providers that add custom data items to the browser tree.
 
Base class for all items in the model.
 
void setSortKey(const QVariant &key)
Sets a custom sorting key for the item.
 
Qgis::BrowserItemType mType
 
void setToolTip(const QString &msg)
 
void dataChanged(QgsDataItem *item)
Emitted when data changes for an item.
 
QVector< QgsDataItem * > children() const
 
virtual void deleteLater()
Safely delete the item:
 
Qgis::BrowserItemType type() const
 
Qgis::BrowserItemState state() const
 
virtual void childrenCreated()
 
QString name() const
Returns the name of the item (the displayed text for the item).
 
virtual void setState(Qgis::BrowserItemState state)
Set item state.
 
virtual void setCapabilities(Qgis::BrowserItemCapabilities capabilities)
Sets the capabilities for the data item.
 
virtual Qgis::BrowserItemCapabilities capabilities2() const
Returns the capabilities for the data item.
 
A browser item for directories: contains subdirectories and layers.
 
QVector< QgsDataItem * > createChildren() override
Create children.
 
Q_DECL_DEPRECATED QWidget * paramWidget() override
 
static Qgis::BrowserDirectoryMonitoring monitoringForPath(const QString &path)
Returns the monitoring setting for a directory path.
 
QgsMimeDataUtils::UriList mimeUris() const override
Returns mime URIs for the data item, most data providers will only return a single URI but some data ...
 
Qgis::BrowserDirectoryMonitoring monitoring() const
Returns the monitoring setting for this directory item.
 
static void setCustomColor(const QString &directory, const QColor &color)
Sets a custom icon color to use for the items for the corresponding directory path.
 
bool equal(const QgsDataItem *other) override
Returns true if this item is equal to another item (by testing item type and path).
 
QString dirPath() const
Returns the full path to the directory the item represents.
 
void setMonitoring(Qgis::BrowserDirectoryMonitoring monitoring)
Sets the monitoring setting for this directory.
 
QColor iconColor() const
Returns the directory's icon color.
 
void childrenCreated() override
 
void setIconColor(const QColor &color)
Sets the directory's icon color.
 
QgsDirectoryItem(QgsDataItem *parent, const QString &name, const QString &path)
Constructor for QgsDirectoryItem, with the specified parent item.
 
void reevaluateMonitoring()
Re-evaluate whether the directory item should be monitored for changes.
 
static bool hiddenPath(const QString &path)
Check if the given path is hidden from the browser model.
 
void setState(Qgis::BrowserItemState state) override
Set item state.
 
static bool pathShouldByMonitoredByDefault(const QString &path)
Returns true if a directory path should be monitored by default.
 
static bool pathIsSlowDevice(const QString &path)
Returns true if the specified path is assumed to reside on a slow device, e.g.
 
static bool isVsiArchiveFileExtension(const QString &extension)
Returns true if a file extension is a supported archive style container (e.g.
 
QList< QgsMimeDataUtils::Uri > UriList
 
QVariant sortKey() const override
Returns the sorting key for the item.
 
QgsProjectHomeItem(QgsDataItem *parent, const QString &name, const QString &dirPath, const QString &path)
Constructor for QgsProjectHomeItem.
 
Data item that can be used to represent QGIS projects.
 
Stores settings for use within QGIS.
 
void endGroup()
Resets the group to what it was before the corresponding beginGroup() call.
 
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
 
void beginGroup(const QString &prefix, QgsSettings::Section section=QgsSettings::NoSection)
Appends prefix to the current group.
 
QStringList childKeys() const
Returns a list of all top-level keys that can be read using the QSettings object.
 
void remove(const QString &key, QgsSettings::Section section=QgsSettings::NoSection)
Removes the setting key and any sub-settings of key in a section.
 
void setValue(const QString &key, const QVariant &value, QgsSettings::Section section=QgsSettings::NoSection)
Sets the value of setting key to value.
 
static QgsDataItem * itemFromPath(QgsDataItem *parent, const QString &path, const QString &name)
Creates a new data item from the specified path.
 
#define QgsDebugMsgLevel(str, level)
 
QString filePath
Path to file, if uri is associated with a file.
 
QString uri
Identifier of the data source recognized by its providerKey.
 
QString name
Human readable name to be used e.g. in layer tree.
 
QString layerType
Type of URI.