31#include <QFileSystemWatcher>
36#include "moc_qgsdirectoryitem.cpp"
58void QgsDirectoryItem::init(
const QString &dirName )
67 mIsSymLink = fi.isSymLink();
70 switch ( mMonitoring )
83 settings.
beginGroup( QStringLiteral(
"qgis/browserPathColors" ) );
85 settingKey.replace(
'/', QLatin1String(
"|||" ) );
86 if ( settings.
childKeys().contains( settingKey ) )
88 const QString colorString = settings.
value( settingKey ).toString();
89 mIconColor = QColor( colorString );
94 setSortKey( QStringLiteral(
" %1" ).arg( dirName ) );
100 switch ( mMonitoring )
113 const QVector<QgsDataItem *> childItems =
children();
116 if (
QgsDirectoryItem *dirItem = qobject_cast< QgsDirectoryItem *>( child ) )
117 dirItem->reevaluateMonitoring();
120 createOrDestroyFileSystemWatcher();
123void QgsDirectoryItem::createOrDestroyFileSystemWatcher()
125 if ( !mMonitored && mFileSystemWatcher )
127 mFileSystemWatcher->deleteLater();
128 mFileSystemWatcher =
nullptr;
132 mFileSystemWatcher =
new QFileSystemWatcher(
this );
133 mFileSystemWatcher->addPath(
mDirPath );
145 if ( color == mIconColor )
155 settings.
beginGroup( QStringLiteral(
"qgis/browserPathColors" ) );
156 QString settingKey = directory;
157 settingKey.replace(
'/', QLatin1String(
"|||" ) );
158 if ( color.isValid() )
159 settings.
setValue( settingKey, color.name( QColor::HexArgb ) );
161 settings.
remove( settingKey );
168 return homeDirIcon( mIconColor, mIconColor.darker() );
175 if ( mIsDir && mIsSymLink )
177 return mIconColor.isValid()
184 return openDirIcon( mIconColor, mIconColor.darker() );
187 return iconDir( mIconColor, mIconColor.darker() );
200 QStringList noMonitorDirs = settings.
value( QStringLiteral(
"qgis/disableMonitorItemUris" ), QStringList() ).toStringList();
201 QStringList alwaysMonitorDirs = settings.
value( QStringLiteral(
"qgis/alwaysMonitorItemUris" ), QStringList() ).toStringList();
203 switch ( mMonitoring )
208 noMonitorDirs.removeAll(
mDirPath );
209 settings.
setValue( QStringLiteral(
"qgis/disableMonitorItemUris" ), noMonitorDirs );
211 alwaysMonitorDirs.removeAll(
mDirPath );
212 settings.
setValue( QStringLiteral(
"qgis/alwaysMonitorItemUris" ), alwaysMonitorDirs );
220 if ( !noMonitorDirs.contains(
mDirPath ) )
223 settings.
setValue( QStringLiteral(
"qgis/disableMonitorItemUris" ), noMonitorDirs );
226 alwaysMonitorDirs.removeAll(
mDirPath );
227 settings.
setValue( QStringLiteral(
"qgis/alwaysMonitorItemUris" ), alwaysMonitorDirs );
235 noMonitorDirs.removeAll(
mDirPath );
236 settings.
setValue( QStringLiteral(
"qgis/disableMonitorItemUris" ), noMonitorDirs );
238 if ( !alwaysMonitorDirs.contains(
mDirPath ) )
240 alwaysMonitorDirs.append(
mDirPath );
241 settings.
setValue( QStringLiteral(
"qgis/alwaysMonitorItemUris" ), alwaysMonitorDirs );
249 const QVector<QgsDataItem *> childItems =
children();
252 if (
QgsDirectoryItem *dirItem = qobject_cast< QgsDirectoryItem *>( child ) )
253 dirItem->reevaluateMonitoring();
256 createOrDestroyFileSystemWatcher();
266 const QStringList entries = dir.entryList( QDir::AllDirs | QDir::NoDotAndDotDot, QDir::Name | QDir::IgnoreCase );
267 for (
const QString &subdir : entries )
275 const QString subdirPath = dir.absoluteFilePath( subdir );
277 QgsDebugMsgLevel( QStringLiteral(
"creating subdir: %1" ).arg( subdirPath ), 2 );
279 const QString
path =
mPath + (
mPath.endsWith(
'/' ) ? QString() : QStringLiteral(
"/" ) ) + subdir;
283 bool handledByProvider =
false;
286 if ( provider->handlesDirectoryPath( subdirPath ) )
288 handledByProvider =
true;
292 if ( handledByProvider )
302 const QStringList fileEntries = dir.entryList( QDir::Dirs | QDir::NoDotAndDotDot | QDir::Files, QDir::Name );
303 for (
const QString &
name : fileEntries )
311 const QString
path = dir.absoluteFilePath(
name );
312 const QFileInfo fileInfo(
path );
323 bool createdItem =
false;
351 if ( fileInfo.suffix().compare( QLatin1String(
"qgs" ), Qt::CaseInsensitive ) == 0 ||
352 fileInfo.suffix().compare( QLatin1String(
"qgz" ), Qt::CaseInsensitive ) == 0 )
371 if ( !mFileSystemWatcher )
373 mFileSystemWatcher =
new QFileSystemWatcher(
this );
374 mFileSystemWatcher->addPath(
mDirPath );
377 mLastScan = QDateTime::currentDateTime();
381 if ( mFileSystemWatcher )
383 delete mFileSystemWatcher;
384 mFileSystemWatcher =
nullptr;
392 if ( mLastScan.msecsTo( QDateTime::currentDateTime() ) <
QgsSettings().value( QStringLiteral(
"browser/minscaninterval" ), 10000 ).toInt() )
399 mRefreshLater =
true;
413 QTimer::singleShot( 100,
this, [
this] {
refresh(); } );
420 const QStringList hiddenItems = settings.
value( QStringLiteral(
"browser/hiddenPaths" ),
421 QStringList() ).toStringList();
422 const int idx = hiddenItems.indexOf(
path );
429 if ( settings.
value( QStringLiteral(
"qgis/disableMonitorItemUris" ), QStringList() ).toStringList().contains(
path ) )
431 else if ( settings.
value( QStringLiteral(
"qgis/alwaysMonitorItemUris" ), QStringList() ).toStringList().contains(
path ) )
440 const QString originalPath = QDir::cleanPath(
path );
441 QString currentPath = originalPath;
443 while ( currentPath != prevPath )
445 prevPath = currentPath;
446 currentPath = QFileInfo( currentPath ).path();
468 return QgsSettings().
value( QStringLiteral(
"/qgis/monitorDirectoriesInBrowser" ),
true ).toBool();
473 QgsDebugMsgLevel( QStringLiteral(
"mRefreshLater = %1" ).arg( mRefreshLater ), 3 );
477 QgsDebugMsgLevel( QStringLiteral(
"directory changed during createChildren() -> refresh() again" ), 3 );
478 mRefreshLater =
false;
487 if ( mFileSystemWatcher && mMonitored )
498 const QgsDirectoryItem *otherDirItem = qobject_cast< const QgsDirectoryItem * >( other );
513 u.
layerType = QStringLiteral(
"directory" );
524 : QTreeWidget( parent )
526 setRootIsDecorated(
false );
531 labels << tr(
"Name" ) << tr(
"Size" ) << tr(
"Date" ) << tr(
"Permissions" ) << tr(
"Owner" ) << tr(
"Group" ) << tr(
"Type" );
532 setHeaderLabels( labels );
539 QList<QTreeWidgetItem *> items;
541 const QDir dir( path );
542 const QStringList entries = dir.entryList( QDir::AllEntries | QDir::NoDotAndDotDot, QDir::Name | QDir::IgnoreCase );
543 for (
const QString &name : entries )
545 const QFileInfo fi( dir.absoluteFilePath( name ) );
549 if ( fi.size() > 1024 )
551 size = QStringLiteral(
"%1 KiB" ).arg( QLocale().toString( fi.size() / 1024.0,
'f', 1 ) );
553 else if ( fi.size() > 1.048576e6 )
555 size = QStringLiteral(
"%1 MiB" ).arg( QLocale().toString( fi.size() / 1.048576e6,
'f', 1 ) );
559 size = QStringLiteral(
"%1 B" ).arg( fi.size() );
562 texts << QLocale().toString( fi.lastModified(), QLocale::ShortFormat );
564 perm += fi.permission( QFile::ReadOwner ) ?
'r' :
'-';
565 perm += fi.permission( QFile::WriteOwner ) ?
'w' :
'-';
566 perm += fi.permission( QFile::ExeOwner ) ?
'x' :
'-';
568 perm += fi.permission( QFile::ReadGroup ) ?
'r' :
'-';
569 perm += fi.permission( QFile::WriteGroup ) ?
'w' :
'-';
570 perm += fi.permission( QFile::ExeGroup ) ?
'x' :
'-';
571 perm += fi.permission( QFile::ReadOther ) ?
'r' :
'-';
572 perm += fi.permission( QFile::WriteOther ) ?
'w' :
'-';
573 perm += fi.permission( QFile::ExeOther ) ?
'x' :
'-';
581 if ( fi.isDir() && fi.isSymLink() )
583 type = tr(
"folder" );
586 else if ( fi.isDir() )
588 type = tr(
"folder" );
589 icon = iconDirectory;
591 else if ( fi.isFile() && fi.isSymLink() )
596 else if ( fi.isFile() )
604 QTreeWidgetItem *item =
new QTreeWidgetItem( texts );
605 item->setIcon( 0, icon );
609 addTopLevelItems( items );
613 const QList<QVariant> lst = settings.
value( QStringLiteral(
"dataitem/directoryHiddenColumns" ) ).toList();
614 for (
const QVariant &colVariant : lst )
616 setColumnHidden( colVariant.toInt(),
true );
622 if ( event->button() == Qt::RightButton )
628 labels << tr(
"Name" ) << tr(
"Size" ) << tr(
"Date" ) << tr(
"Permissions" ) << tr(
"Owner" ) << tr(
"Group" ) << tr(
"Type" );
629 for (
int i = 0; i < labels.count(); i++ )
632 action->setObjectName( QString::number( i ) );
633 action->setCheckable(
true );
634 action->setChecked( !isColumnHidden( i ) );
637 popupMenu.exec( event->globalPos() );
643 QAction *action = qobject_cast<QAction *>( sender() );
647 const int columnIndex = action->objectName().toInt();
648 setColumnHidden( columnIndex, !isColumnHidden( columnIndex ) );
653 for (
int i = 0; i < columnCount(); i++ )
655 if ( isColumnHidden( i ) )
656 lst.append( QVariant( i ) );
658 settings.
setValue( QStringLiteral(
"dataitem/directoryHiddenColumns" ), lst );
679 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.
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.
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.