27 #include <QFileSystemWatcher>
29 #include <QMouseEvent>
46 const QString &dirPath,
const QString &path,
47 const QString &providerKey )
62 switch ( mMonitoring )
75 settings.
beginGroup( QStringLiteral(
"qgis/browserPathColors" ) );
77 settingKey.replace(
'/', QLatin1String(
"|||" ) );
78 if ( settings.
childKeys().contains( settingKey ) )
80 const QString colorString = settings.
value( settingKey ).toString();
81 mIconColor = QColor( colorString );
89 switch ( mMonitoring )
102 const QVector<QgsDataItem *> childItems =
children();
105 if (
QgsDirectoryItem *dirItem = qobject_cast< QgsDirectoryItem *>( child ) )
106 dirItem->reevaluateMonitoring();
109 createOrDestroyFileSystemWatcher();
112 void QgsDirectoryItem::createOrDestroyFileSystemWatcher()
114 if ( !mMonitored && mFileSystemWatcher )
116 mFileSystemWatcher->deleteLater();
117 mFileSystemWatcher =
nullptr;
121 mFileSystemWatcher =
new QFileSystemWatcher(
this );
122 mFileSystemWatcher->addPath(
mDirPath );
134 if ( color == mIconColor )
144 settings.
beginGroup( QStringLiteral(
"qgis/browserPathColors" ) );
145 QString settingKey = directory;
146 settingKey.replace(
'/', QLatin1String(
"|||" ) );
147 if ( color.isValid() )
148 settings.
setValue( settingKey, color.name( QColor::HexArgb ) );
150 settings.
remove( settingKey );
157 return homeDirIcon( mIconColor, mIconColor.darker() );
165 if ( fi.isDir() && fi.isSymLink() )
167 return mIconColor.isValid()
174 return openDirIcon( mIconColor, mIconColor.darker() );
177 return iconDir( mIconColor, mIconColor.darker() );
190 QStringList noMonitorDirs = settings.
value( QStringLiteral(
"qgis/disableMonitorItemUris" ), QStringList() ).toStringList();
191 QStringList alwaysMonitorDirs = settings.
value( QStringLiteral(
"qgis/alwaysMonitorItemUris" ), QStringList() ).toStringList();
193 switch ( mMonitoring )
198 noMonitorDirs.removeAll(
mDirPath );
199 settings.
setValue( QStringLiteral(
"qgis/disableMonitorItemUris" ), noMonitorDirs );
201 alwaysMonitorDirs.removeAll(
mDirPath );
202 settings.
setValue( QStringLiteral(
"qgis/alwaysMonitorItemUris" ), alwaysMonitorDirs );
210 if ( !noMonitorDirs.contains(
mDirPath ) )
213 settings.
setValue( QStringLiteral(
"qgis/disableMonitorItemUris" ), noMonitorDirs );
216 alwaysMonitorDirs.removeAll(
mDirPath );
217 settings.
setValue( QStringLiteral(
"qgis/alwaysMonitorItemUris" ), alwaysMonitorDirs );
225 noMonitorDirs.removeAll(
mDirPath );
226 settings.
setValue( QStringLiteral(
"qgis/disableMonitorItemUris" ), noMonitorDirs );
228 if ( !alwaysMonitorDirs.contains(
mDirPath ) )
230 alwaysMonitorDirs.append(
mDirPath );
231 settings.
setValue( QStringLiteral(
"qgis/alwaysMonitorItemUris" ), alwaysMonitorDirs );
239 const QVector<QgsDataItem *> childItems =
children();
242 if (
QgsDirectoryItem *dirItem = qobject_cast< QgsDirectoryItem *>( child ) )
243 dirItem->reevaluateMonitoring();
246 createOrDestroyFileSystemWatcher();
256 const QStringList entries = dir.entryList( QDir::AllDirs | QDir::NoDotAndDotDot, QDir::Name | QDir::IgnoreCase );
257 for (
const QString &subdir : entries )
265 const QString subdirPath = dir.absoluteFilePath( subdir );
267 QgsDebugMsgLevel( QStringLiteral(
"creating subdir: %1" ).arg( subdirPath ), 2 );
269 const QString
path =
mPath +
'/' + subdir;
273 bool handledByProvider =
false;
276 if ( provider->handlesDirectoryPath(
path ) )
278 handledByProvider =
true;
282 if ( handledByProvider )
288 item->
setSortKey( QStringLiteral(
" %1" ).arg( subdir ) );
295 const QStringList fileEntries = dir.entryList( QDir::Dirs | QDir::NoDotAndDotDot | QDir::Files, QDir::Name );
296 for (
const QString &
name : fileEntries )
304 const QString
path = dir.absoluteFilePath(
name );
305 const QFileInfo fileInfo(
path );
307 if ( fileInfo.suffix().compare( QLatin1String(
"zip" ), Qt::CaseInsensitive ) == 0 ||
308 fileInfo.suffix().compare( QLatin1String(
"tar" ), Qt::CaseInsensitive ) == 0 )
318 bool createdItem =
false;
321 const int capabilities = provider->capabilities();
346 if ( fileInfo.suffix().compare( QLatin1String(
"qgs" ), Qt::CaseInsensitive ) == 0 ||
347 fileInfo.suffix().compare( QLatin1String(
"qgz" ), Qt::CaseInsensitive ) == 0 )
366 if ( !mFileSystemWatcher )
368 mFileSystemWatcher =
new QFileSystemWatcher(
this );
369 mFileSystemWatcher->addPath(
mDirPath );
372 mLastScan = QDateTime::currentDateTime();
376 if ( mFileSystemWatcher )
378 delete mFileSystemWatcher;
379 mFileSystemWatcher =
nullptr;
387 if ( mLastScan.msecsTo( QDateTime::currentDateTime() ) <
QgsSettings().value( QStringLiteral(
"browser/minscaninterval" ), 10000 ).toInt() )
394 mRefreshLater =
true;
408 QTimer::singleShot( 100,
this, [ = ] {
refresh(); } );
415 const QStringList hiddenItems = settings.
value( QStringLiteral(
"browser/hiddenPaths" ),
416 QStringList() ).toStringList();
417 const int idx = hiddenItems.indexOf(
path );
424 if ( settings.
value( QStringLiteral(
"qgis/disableMonitorItemUris" ), QStringList() ).toStringList().contains(
path ) )
426 else if ( settings.
value( QStringLiteral(
"qgis/alwaysMonitorItemUris" ), QStringList() ).toStringList().contains(
path ) )
435 const QString originalPath = QDir::cleanPath(
path );
436 QString currentPath = originalPath;
438 while ( currentPath != prevPath )
440 prevPath = currentPath;
441 currentPath = QFileInfo( currentPath ).path();
461 return QgsSettings().
value( QStringLiteral(
"/qgis/monitorDirectoriesInBrowser" ),
true ).toBool();
466 QgsDebugMsgLevel( QStringLiteral(
"mRefreshLater = %1" ).arg( mRefreshLater ), 3 );
470 QgsDebugMsgLevel( QStringLiteral(
"directory changed during createChidren() -> refresh() again" ), 3 );
471 mRefreshLater =
false;
480 if ( mFileSystemWatcher && mMonitored )
502 u.
layerType = QStringLiteral(
"directory" );
513 : QTreeWidget( parent )
515 setRootIsDecorated(
false );
520 labels << tr(
"Name" ) << tr(
"Size" ) << tr(
"Date" ) << tr(
"Permissions" ) << tr(
"Owner" ) << tr(
"Group" ) << tr(
"Type" );
521 setHeaderLabels( labels );
528 QList<QTreeWidgetItem *> items;
530 const QDir dir( path );
531 const QStringList entries = dir.entryList( QDir::AllEntries | QDir::NoDotAndDotDot, QDir::Name | QDir::IgnoreCase );
532 for (
const QString &name : entries )
534 const QFileInfo fi( dir.absoluteFilePath( name ) );
538 if ( fi.size() > 1024 )
540 size = QStringLiteral(
"%1 KiB" ).arg( QLocale().toString( fi.size() / 1024.0,
'f', 1 ) );
542 else if ( fi.size() > 1.048576e6 )
544 size = QStringLiteral(
"%1 MiB" ).arg( QLocale().toString( fi.size() / 1.048576e6,
'f', 1 ) );
548 size = QStringLiteral(
"%1 B" ).arg( fi.size() );
551 texts << QLocale().toString( fi.lastModified(), QLocale::ShortFormat );
553 perm += fi.permission( QFile::ReadOwner ) ?
'r' :
'-';
554 perm += fi.permission( QFile::WriteOwner ) ?
'w' :
'-';
555 perm += fi.permission( QFile::ExeOwner ) ?
'x' :
'-';
557 perm += fi.permission( QFile::ReadGroup ) ?
'r' :
'-';
558 perm += fi.permission( QFile::WriteGroup ) ?
'w' :
'-';
559 perm += fi.permission( QFile::ExeGroup ) ?
'x' :
'-';
560 perm += fi.permission( QFile::ReadOther ) ?
'r' :
'-';
561 perm += fi.permission( QFile::WriteOther ) ?
'w' :
'-';
562 perm += fi.permission( QFile::ExeOther ) ?
'x' :
'-';
570 if ( fi.isDir() && fi.isSymLink() )
572 type = tr(
"folder" );
575 else if ( fi.isDir() )
577 type = tr(
"folder" );
578 icon = iconDirectory;
580 else if ( fi.isFile() && fi.isSymLink() )
585 else if ( fi.isFile() )
593 QTreeWidgetItem *item =
new QTreeWidgetItem( texts );
594 item->setIcon( 0, icon );
598 addTopLevelItems( items );
602 const QList<QVariant> lst = settings.
value( QStringLiteral(
"dataitem/directoryHiddenColumns" ) ).toList();
603 for (
const QVariant &colVariant : lst )
605 setColumnHidden( colVariant.toInt(),
true );
611 if ( event->button() == Qt::RightButton )
617 labels << tr(
"Name" ) << tr(
"Size" ) << tr(
"Date" ) << tr(
"Permissions" ) << tr(
"Owner" ) << tr(
"Group" ) << tr(
"Type" );
618 for (
int i = 0; i < labels.count(); i++ )
621 action->setObjectName( QString::number( i ) );
622 action->setCheckable(
true );
623 action->setChecked( !isColumnHidden( i ) );
626 popupMenu.exec( event->globalPos() );
632 QAction *action = qobject_cast<QAction *>( sender() );
636 const int columnIndex = action->objectName().toInt();
637 setColumnHidden( columnIndex, !isColumnHidden( columnIndex ) );
642 for (
int i = 0; i < columnCount(); i++ )
644 if ( isColumnHidden( i ) )
645 lst.append( QVariant( i ) );
647 settings.
setValue( QStringLiteral(
"dataitem/directoryHiddenColumns" ), lst );
655 :
QgsDirectoryItem( parent, name, dirPath, path, QStringLiteral(
"special:ProjectHome" ) )
668 return QStringLiteral(
" 1" );