27#include <QFileSystemWatcher>
46 const QString &dirPath,
const QString &path,
47 const QString &providerKey )
54void QgsDirectoryItem::init(
const QString &dirName )
63 mIsSymLink = fi.isSymLink();
66 switch ( mMonitoring )
79 settings.
beginGroup( QStringLiteral(
"qgis/browserPathColors" ) );
81 settingKey.replace(
'/', QLatin1String(
"|||" ) );
82 if ( settings.
childKeys().contains( settingKey ) )
84 const QString colorString = settings.
value( settingKey ).toString();
85 mIconColor = QColor( colorString );
90 setSortKey( QStringLiteral(
" %1" ).arg( dirName ) );
96 switch ( mMonitoring )
109 const QVector<QgsDataItem *> childItems =
children();
112 if (
QgsDirectoryItem *dirItem = qobject_cast< QgsDirectoryItem *>( child ) )
113 dirItem->reevaluateMonitoring();
116 createOrDestroyFileSystemWatcher();
119void QgsDirectoryItem::createOrDestroyFileSystemWatcher()
121 if ( !mMonitored && mFileSystemWatcher )
123 mFileSystemWatcher->deleteLater();
124 mFileSystemWatcher =
nullptr;
128 mFileSystemWatcher =
new QFileSystemWatcher(
this );
129 mFileSystemWatcher->addPath(
mDirPath );
141 if ( color == mIconColor )
151 settings.
beginGroup( QStringLiteral(
"qgis/browserPathColors" ) );
152 QString settingKey = directory;
153 settingKey.replace(
'/', QLatin1String(
"|||" ) );
154 if ( color.isValid() )
155 settings.
setValue( settingKey, color.name( QColor::HexArgb ) );
157 settings.
remove( settingKey );
164 return homeDirIcon( mIconColor, mIconColor.darker() );
171 if ( mIsDir && mIsSymLink )
173 return mIconColor.isValid()
180 return openDirIcon( mIconColor, mIconColor.darker() );
183 return iconDir( mIconColor, mIconColor.darker() );
196 QStringList noMonitorDirs = settings.
value( QStringLiteral(
"qgis/disableMonitorItemUris" ), QStringList() ).toStringList();
197 QStringList alwaysMonitorDirs = settings.
value( QStringLiteral(
"qgis/alwaysMonitorItemUris" ), QStringList() ).toStringList();
199 switch ( mMonitoring )
204 noMonitorDirs.removeAll(
mDirPath );
205 settings.
setValue( QStringLiteral(
"qgis/disableMonitorItemUris" ), noMonitorDirs );
207 alwaysMonitorDirs.removeAll(
mDirPath );
208 settings.
setValue( QStringLiteral(
"qgis/alwaysMonitorItemUris" ), alwaysMonitorDirs );
216 if ( !noMonitorDirs.contains(
mDirPath ) )
219 settings.
setValue( QStringLiteral(
"qgis/disableMonitorItemUris" ), noMonitorDirs );
222 alwaysMonitorDirs.removeAll(
mDirPath );
223 settings.
setValue( QStringLiteral(
"qgis/alwaysMonitorItemUris" ), alwaysMonitorDirs );
231 noMonitorDirs.removeAll(
mDirPath );
232 settings.
setValue( QStringLiteral(
"qgis/disableMonitorItemUris" ), noMonitorDirs );
234 if ( !alwaysMonitorDirs.contains(
mDirPath ) )
236 alwaysMonitorDirs.append(
mDirPath );
237 settings.
setValue( QStringLiteral(
"qgis/alwaysMonitorItemUris" ), alwaysMonitorDirs );
245 const QVector<QgsDataItem *> childItems =
children();
248 if (
QgsDirectoryItem *dirItem = qobject_cast< QgsDirectoryItem *>( child ) )
249 dirItem->reevaluateMonitoring();
252 createOrDestroyFileSystemWatcher();
262 const QStringList entries = dir.entryList( QDir::AllDirs | QDir::NoDotAndDotDot, QDir::Name | QDir::IgnoreCase );
263 for (
const QString &subdir : entries )
271 const QString subdirPath = dir.absoluteFilePath( subdir );
273 QgsDebugMsgLevel( QStringLiteral(
"creating subdir: %1" ).arg( subdirPath ), 2 );
275 const QString
path =
mPath + (
mPath.endsWith(
'/' ) ? QString() : QStringLiteral(
"/" ) ) + subdir;
279 bool handledByProvider =
false;
282 if ( provider->handlesDirectoryPath( subdirPath ) )
284 handledByProvider =
true;
288 if ( handledByProvider )
298 const QStringList fileEntries = dir.entryList( QDir::Dirs | QDir::NoDotAndDotDot | QDir::Files, QDir::Name );
299 for (
const QString &
name : fileEntries )
307 const QString
path = dir.absoluteFilePath(
name );
308 const QFileInfo fileInfo(
path );
319 bool createdItem =
false;
347 if ( fileInfo.suffix().compare( QLatin1String(
"qgs" ), Qt::CaseInsensitive ) == 0 ||
348 fileInfo.suffix().compare( QLatin1String(
"qgz" ), Qt::CaseInsensitive ) == 0 )
367 if ( !mFileSystemWatcher )
369 mFileSystemWatcher =
new QFileSystemWatcher(
this );
370 mFileSystemWatcher->addPath(
mDirPath );
373 mLastScan = QDateTime::currentDateTime();
377 if ( mFileSystemWatcher )
379 delete mFileSystemWatcher;
380 mFileSystemWatcher =
nullptr;
388 if ( mLastScan.msecsTo( QDateTime::currentDateTime() ) <
QgsSettings().value( QStringLiteral(
"browser/minscaninterval" ), 10000 ).toInt() )
395 mRefreshLater =
true;
409 QTimer::singleShot( 100,
this, [
this] {
refresh(); } );
416 const QStringList hiddenItems = settings.
value( QStringLiteral(
"browser/hiddenPaths" ),
417 QStringList() ).toStringList();
418 const int idx = hiddenItems.indexOf(
path );
425 if ( settings.
value( QStringLiteral(
"qgis/disableMonitorItemUris" ), QStringList() ).toStringList().contains(
path ) )
427 else if ( settings.
value( QStringLiteral(
"qgis/alwaysMonitorItemUris" ), QStringList() ).toStringList().contains(
path ) )
436 const QString originalPath = QDir::cleanPath(
path );
437 QString currentPath = originalPath;
439 while ( currentPath != prevPath )
441 prevPath = currentPath;
442 currentPath = QFileInfo( currentPath ).path();
464 return QgsSettings().
value( QStringLiteral(
"/qgis/monitorDirectoriesInBrowser" ),
true ).toBool();
469 QgsDebugMsgLevel( QStringLiteral(
"mRefreshLater = %1" ).arg( mRefreshLater ), 3 );
473 QgsDebugMsgLevel( QStringLiteral(
"directory changed during createChildren() -> refresh() again" ), 3 );
474 mRefreshLater =
false;
483 if ( mFileSystemWatcher && mMonitored )
494 const QgsDirectoryItem *otherDirItem = qobject_cast< const QgsDirectoryItem * >( other );
509 u.
layerType = QStringLiteral(
"directory" );
520 : QTreeWidget( parent )
522 setRootIsDecorated(
false );
527 labels << tr(
"Name" ) << tr(
"Size" ) << tr(
"Date" ) << tr(
"Permissions" ) << tr(
"Owner" ) << tr(
"Group" ) << tr(
"Type" );
528 setHeaderLabels( labels );
535 QList<QTreeWidgetItem *> items;
537 const QDir dir( path );
538 const QStringList entries = dir.entryList( QDir::AllEntries | QDir::NoDotAndDotDot, QDir::Name | QDir::IgnoreCase );
539 for (
const QString &name : entries )
541 const QFileInfo fi( dir.absoluteFilePath( name ) );
545 if ( fi.size() > 1024 )
547 size = QStringLiteral(
"%1 KiB" ).arg( QLocale().toString( fi.size() / 1024.0,
'f', 1 ) );
549 else if ( fi.size() > 1.048576e6 )
551 size = QStringLiteral(
"%1 MiB" ).arg( QLocale().toString( fi.size() / 1.048576e6,
'f', 1 ) );
555 size = QStringLiteral(
"%1 B" ).arg( fi.size() );
558 texts << QLocale().toString( fi.lastModified(), QLocale::ShortFormat );
560 perm += fi.permission( QFile::ReadOwner ) ?
'r' :
'-';
561 perm += fi.permission( QFile::WriteOwner ) ?
'w' :
'-';
562 perm += fi.permission( QFile::ExeOwner ) ?
'x' :
'-';
564 perm += fi.permission( QFile::ReadGroup ) ?
'r' :
'-';
565 perm += fi.permission( QFile::WriteGroup ) ?
'w' :
'-';
566 perm += fi.permission( QFile::ExeGroup ) ?
'x' :
'-';
567 perm += fi.permission( QFile::ReadOther ) ?
'r' :
'-';
568 perm += fi.permission( QFile::WriteOther ) ?
'w' :
'-';
569 perm += fi.permission( QFile::ExeOther ) ?
'x' :
'-';
577 if ( fi.isDir() && fi.isSymLink() )
579 type = tr(
"folder" );
582 else if ( fi.isDir() )
584 type = tr(
"folder" );
585 icon = iconDirectory;
587 else if ( fi.isFile() && fi.isSymLink() )
592 else if ( fi.isFile() )
600 QTreeWidgetItem *item =
new QTreeWidgetItem( texts );
601 item->setIcon( 0, icon );
605 addTopLevelItems( items );
609 const QList<QVariant> lst = settings.
value( QStringLiteral(
"dataitem/directoryHiddenColumns" ) ).toList();
610 for (
const QVariant &colVariant : lst )
612 setColumnHidden( colVariant.toInt(),
true );
618 if ( event->button() == Qt::RightButton )
624 labels << tr(
"Name" ) << tr(
"Size" ) << tr(
"Date" ) << tr(
"Permissions" ) << tr(
"Owner" ) << tr(
"Group" ) << tr(
"Type" );
625 for (
int i = 0; i < labels.count(); i++ )
628 action->setObjectName( QString::number( i ) );
629 action->setCheckable(
true );
630 action->setChecked( !isColumnHidden( i ) );
633 popupMenu.exec( event->globalPos() );
639 QAction *action = qobject_cast<QAction *>( sender() );
643 const int columnIndex = action->objectName().toInt();
644 setColumnHidden( columnIndex, !isColumnHidden( columnIndex ) );
649 for (
int i = 0; i < columnCount(); i++ )
651 if ( isColumnHidden( i ) )
652 lst.append( QVariant( i ) );
654 settings.
setValue( QStringLiteral(
"dataitem/directoryHiddenColumns" ), lst );
662 :
QgsDirectoryItem( parent, name, dirPath, path, QStringLiteral(
"special:ProjectHome" ) )
675 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 Collection: logical collection of layers or subcollections, e.g.
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.
This is the interface for those who want to 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 directory: contains subdirectories and layers.
QVector< QgsDataItem * > createChildren() override
Create children.
Q_DECL_DEPRECATED QWidget * paramWidget() override
Returns source widget from data item for QgsBrowserPropertiesWidget.
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.
This class is a composition of two QSettings instances:
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.