33#include <QFileSystemWatcher>
39#include "moc_qgsdirectoryitem.cpp"
41using namespace Qt::StringLiterals;
44 =
new QgsSettingsEntryBool( u
"monitor-directories-in-browser"_s,
QgsSettingsTree::sTreeQgis,
true, u
"If true, directories are automatically monitored and refreshed in the browser when their contents change outside of QGIS."_s );
77void QgsDirectoryItem::init(
const QString &dirName )
84 mIsSymLink = fi.isSymLink();
87 switch ( mMonitoring )
101 settingKey.replace(
'/',
"|||"_L1 );
114 switch ( mMonitoring )
127 const QVector<QgsDataItem *> childItems =
children();
130 if (
QgsDirectoryItem *dirItem = qobject_cast< QgsDirectoryItem *>( child ) )
131 dirItem->reevaluateMonitoring();
134 createOrDestroyFileSystemWatcher();
137void QgsDirectoryItem::createOrDestroyFileSystemWatcher()
139 if ( !mMonitored && mFileSystemWatcher )
141 mFileSystemWatcher->deleteLater();
142 mFileSystemWatcher =
nullptr;
146 mFileSystemWatcher =
new QFileSystemWatcher(
this );
147 mFileSystemWatcher->addPath(
mDirPath );
159 if ( color == mIconColor )
168 QString settingKey = directory;
169 settingKey.replace(
'/',
"|||"_L1 );
170 if ( color.isValid() )
179 return homeDirIcon( mIconColor, mIconColor.darker() );
186 if ( mIsDir && mIsSymLink )
193 return openDirIcon( mIconColor, mIconColor.darker() );
196 return iconDir( mIconColor, mIconColor.darker() );
211 switch ( mMonitoring )
216 noMonitorDirs.removeAll(
mDirPath );
219 alwaysMonitorDirs.removeAll(
mDirPath );
228 if ( !noMonitorDirs.contains(
mDirPath ) )
234 alwaysMonitorDirs.removeAll(
mDirPath );
243 noMonitorDirs.removeAll(
mDirPath );
246 if ( !alwaysMonitorDirs.contains(
mDirPath ) )
248 alwaysMonitorDirs.append(
mDirPath );
257 const QVector<QgsDataItem *> childItems =
children();
260 if (
QgsDirectoryItem *dirItem = qobject_cast< QgsDirectoryItem *>( child ) )
261 dirItem->reevaluateMonitoring();
264 createOrDestroyFileSystemWatcher();
274 const QStringList entries = dir.entryList( QDir::AllDirs | QDir::NoDotAndDotDot, QDir::Name | QDir::IgnoreCase );
275 for (
const QString &subdir : entries )
283 const QString subdirPath = dir.absoluteFilePath( subdir );
287 const QString
path =
mPath + (
mPath.endsWith(
'/' ) ? QString() : u
"/"_s ) + subdir;
291 bool handledByProvider =
false;
294 if ( provider->handlesDirectoryPath( subdirPath ) )
296 handledByProvider =
true;
300 if ( handledByProvider )
310 const QStringList fileEntries = dir.entryList( QDir::Dirs | QDir::NoDotAndDotDot | QDir::Files, QDir::Name );
311 for (
const QString &
name : fileEntries )
319 const QString
path = dir.absoluteFilePath(
name );
320 const QFileInfo fileInfo(
path );
331 bool createdItem =
false;
358 if ( fileInfo.suffix().compare(
"qgs"_L1, Qt::CaseInsensitive ) == 0 || fileInfo.suffix().compare(
"qgz"_L1, Qt::CaseInsensitive ) == 0 )
376 if ( !mFileSystemWatcher )
378 mFileSystemWatcher =
new QFileSystemWatcher(
this );
379 mFileSystemWatcher->addPath(
mDirPath );
382 mLastScan = QDateTime::currentDateTime();
386 if ( mFileSystemWatcher )
388 delete mFileSystemWatcher;
389 mFileSystemWatcher =
nullptr;
404 mRefreshLater =
true;
418 QTimer::singleShot( 100,
this, [
this] {
refresh(); } );
425 const int idx = hiddenItems.indexOf(
path );
442 const QString originalPath = QDir::cleanPath(
path );
443 QString currentPath = originalPath;
445 while ( currentPath != prevPath )
447 prevPath = currentPath;
448 currentPath = QFileInfo( currentPath ).path();
479 QgsDebugMsgLevel( u
"directory changed during createChildren() -> refresh() again"_s, 3 );
480 mRefreshLater =
false;
489 if ( mFileSystemWatcher && mMonitored )
500 const QgsDirectoryItem *otherDirItem = qobject_cast< const QgsDirectoryItem * >( other );
526 : QTreeWidget( parent )
528 setRootIsDecorated(
false );
533 labels << tr(
"Name" ) << tr(
"Size" ) << tr(
"Date" ) << tr(
"Permissions" ) << tr(
"Owner" ) << tr(
"Group" ) << tr(
"Type" );
534 setHeaderLabels( labels );
541 QList<QTreeWidgetItem *> items;
543 const QDir dir( path );
544 const QStringList entries = dir.entryList( QDir::AllEntries | QDir::NoDotAndDotDot, QDir::Name | QDir::IgnoreCase );
545 for (
const QString &name : entries )
547 const QFileInfo fi( dir.absoluteFilePath( name ) );
551 if ( fi.size() > 1024 )
553 size = u
"%1 KiB"_s.arg( QLocale().toString( fi.size() / 1024.0,
'f', 1 ) );
555 else if ( fi.size() > 1.048576e6 )
557 size = u
"%1 MiB"_s.arg( QLocale().toString( fi.size() / 1.048576e6,
'f', 1 ) );
561 size = u
"%1 B"_s.arg( fi.size() );
564 texts << QLocale().toString( fi.lastModified(), QLocale::ShortFormat );
566 perm += fi.permission( QFile::ReadOwner ) ?
'r' :
'-';
567 perm += fi.permission( QFile::WriteOwner ) ?
'w' :
'-';
568 perm += fi.permission( QFile::ExeOwner ) ?
'x' :
'-';
570 perm += fi.permission( QFile::ReadGroup ) ?
'r' :
'-';
571 perm += fi.permission( QFile::WriteGroup ) ?
'w' :
'-';
572 perm += fi.permission( QFile::ExeGroup ) ?
'x' :
'-';
573 perm += fi.permission( QFile::ReadOther ) ?
'r' :
'-';
574 perm += fi.permission( QFile::WriteOther ) ?
'w' :
'-';
575 perm += fi.permission( QFile::ExeOther ) ?
'x' :
'-';
583 if ( fi.isDir() && fi.isSymLink() )
585 type = tr(
"folder" );
588 else if ( fi.isDir() )
590 type = tr(
"folder" );
591 icon = iconDirectory;
593 else if ( fi.isFile() && fi.isSymLink() )
598 else if ( fi.isFile() )
606 QTreeWidgetItem *item =
new QTreeWidgetItem( texts );
607 item->setIcon( 0, icon );
611 addTopLevelItems( items );
615 for (
const QVariant &colVariant : lst )
617 setColumnHidden( colVariant.toInt(),
true );
623 if ( event->button() == Qt::RightButton )
629 labels << tr(
"Name" ) << tr(
"Size" ) << tr(
"Date" ) << tr(
"Permissions" ) << tr(
"Owner" ) << tr(
"Group" ) << tr(
"Type" );
630 for (
int i = 0; i < labels.count(); i++ )
633 action->setObjectName( QString::number( i ) );
634 action->setCheckable(
true );
635 action->setChecked( !isColumnHidden( i ) );
638 popupMenu.exec( event->globalPos() );
644 QAction *action = qobject_cast<QAction *>( sender() );
648 const int columnIndex = action->objectName().toInt();
649 setColumnHidden( columnIndex, !isColumnHidden( columnIndex ) );
653 for (
int i = 0; i < columnCount(); i++ )
655 if ( isColumnHidden( i ) )
656 lst.append( QVariant( i ) );
@ 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.
static QIcon homeDirIcon(const QColor &fillColor=QColor(), const QColor &strokeColor=QColor())
Shared home directory icon.
QgsDataCollectionItem(QgsDataItem *parent, const QString &name, const QString &path=QString(), const QString &providerKey=QString())
Constructor for QgsDataCollectionItem, with the specified parent item.
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.
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
QgsDataItem(Qgis::BrowserItemType type, QgsDataItem *parent, const QString &name, const QString &path, const QString &providerKey=QString())
Constructor for QgsDataItem, with the specified parent item.
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.
QgsDataItem * parent() const
Gets item parent.
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.
static const QgsSettingsEntryString * settingsCustomPathColor
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.
static const QgsSettingsEntryInteger * settingsMinScanInterval
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.
static const QgsSettingsEntryBool * settingsMonitorDirectoriesInBrowser
static const QgsSettingsEntryStringList * settingsHiddenPaths
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.
static const QgsSettingsEntryStringList * settingsAlwaysMonitorItemUris
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 const QgsSettingsEntryStringList * settingsDisableMonitorItemUris
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.
A boolean settings entry.
An integer settings entry.
A string list settings entry.
A variant settings entry.
static QgsSettingsTreeNode * sTreeBrowser
static QgsSettingsTreeNode * sTreeQgis
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.