19 #include "qgssettings.h" 
   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 )
 
  143   QgsSettings settings;
 
  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() );
 
  189   QgsSettings settings;
 
  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   QStringList entries = dir.entryList( QDir::AllDirs | QDir::NoDotAndDotDot, QDir::Name | QDir::IgnoreCase );
 
  257   const auto constEntries = entries;
 
  258   for ( 
const QString &subdir : constEntries )
 
  266     QString subdirPath = dir.absoluteFilePath( subdir );
 
  268     QgsDebugMsgLevel( QStringLiteral( 
"creating subdir: %1" ).arg( subdirPath ), 2 );
 
  274     bool handledByProvider = 
false;
 
  277       if ( provider->handlesDirectoryPath( 
path ) )
 
  279         handledByProvider = 
true;
 
  283     if ( handledByProvider )
 
  289     item->
setSortKey( QStringLiteral( 
"  %1" ).arg( subdir ) );
 
  296   QStringList fileEntries = dir.entryList( QDir::Dirs | QDir::NoDotAndDotDot | QDir::Files, QDir::Name );
 
  297   const auto constFileEntries = fileEntries;
 
  298   for ( 
const QString &
name : constFileEntries )
 
  306     QString 
path = dir.absoluteFilePath( 
name );
 
  307     QFileInfo fileInfo( 
path );
 
  309     if ( fileInfo.suffix().compare( QLatin1String( 
"zip" ), Qt::CaseInsensitive ) == 0 ||
 
  310          fileInfo.suffix().compare( QLatin1String( 
"tar" ), Qt::CaseInsensitive ) == 0 )
 
  320     bool createdItem = 
false;
 
  323       int capabilities = provider->capabilities();
 
  343       if ( fileInfo.suffix().compare( QLatin1String( 
"qgs" ), Qt::CaseInsensitive ) == 0 ||
 
  344            fileInfo.suffix().compare( QLatin1String( 
"qgz" ), Qt::CaseInsensitive ) == 0 )
 
  362     if ( !mFileSystemWatcher )
 
  364       mFileSystemWatcher = 
new QFileSystemWatcher( 
this );
 
  365       mFileSystemWatcher->addPath( 
mDirPath );
 
  368     mLastScan = QDateTime::currentDateTime();
 
  372     if ( mFileSystemWatcher )
 
  374       delete mFileSystemWatcher;
 
  375       mFileSystemWatcher = 
nullptr;
 
  383   if ( mLastScan.msecsTo( QDateTime::currentDateTime() ) < QgsSettings().value( QStringLiteral( 
"browser/minscaninterval" ), 10000 ).toInt() )
 
  390     mRefreshLater = 
true;
 
  404     QTimer::singleShot( 100, 
this, [ = ] { 
refresh(); } );
 
  410   QgsSettings settings;
 
  411   QStringList hiddenItems = settings.value( QStringLiteral( 
"browser/hiddenPaths" ),
 
  412                             QStringList() ).toStringList();
 
  413   int idx = hiddenItems.indexOf( 
path );
 
  419   QgsSettings settings;
 
  420   if ( settings.value( QStringLiteral( 
"qgis/disableMonitorItemUris" ), QStringList() ).toStringList().contains( 
path ) )
 
  422   else if ( settings.value( QStringLiteral( 
"qgis/alwaysMonitorItemUris" ), QStringList() ).toStringList().contains( 
path ) )
 
  431   const QString originalPath = QDir::cleanPath( 
path );
 
  432   QString currentPath = originalPath;
 
  434   while ( currentPath != prevPath )
 
  436     prevPath = currentPath;
 
  437     currentPath = QFileInfo( currentPath ).path();
 
  457   return QgsSettings().value( QStringLiteral( 
"/qgis/monitorDirectoriesInBrowser" ), 
true ).toBool();
 
  462   QgsDebugMsgLevel( QStringLiteral( 
"mRefreshLater = %1" ).arg( mRefreshLater ), 3 );
 
  466     QgsDebugMsgLevel( QStringLiteral( 
"directory changed during createChidren() -> refresh() again" ), 3 );
 
  467     mRefreshLater = 
false;
 
  476   if ( mFileSystemWatcher && mMonitored )
 
  498   u.
layerType = QStringLiteral( 
"directory" );
 
  508   : QTreeWidget( parent )
 
  510   setRootIsDecorated( 
false );
 
  515   labels << tr( 
"Name" ) << tr( 
"Size" ) << tr( 
"Date" ) << tr( 
"Permissions" ) << tr( 
"Owner" ) << tr( 
"Group" ) << tr( 
"Type" );
 
  516   setHeaderLabels( labels );
 
  523   QList<QTreeWidgetItem *> items;
 
  526   QStringList entries = dir.entryList( QDir::AllEntries | QDir::NoDotAndDotDot, QDir::Name | QDir::IgnoreCase );
 
  527   const auto constEntries = entries;
 
  528   for ( 
const QString &name : constEntries )
 
  530     QFileInfo fi( dir.absoluteFilePath( name ) );
 
  534     if ( fi.size() > 1024 )
 
  536       size = QStringLiteral( 
"%1 KiB" ).arg( QString::number( fi.size() / 1024.0, 
'f', 1 ) );
 
  538     else if ( fi.size() > 1.048576e6 )
 
  540       size = QStringLiteral( 
"%1 MiB" ).arg( QString::number( fi.size() / 1.048576e6, 
'f', 1 ) );
 
  544       size = QStringLiteral( 
"%1 B" ).arg( fi.size() );
 
  547     texts << QLocale().toString( fi.lastModified(), QLocale::ShortFormat );
 
  549     perm += fi.permission( QFile::ReadOwner ) ? 
'r' : 
'-';
 
  550     perm += fi.permission( QFile::WriteOwner ) ? 
'w' : 
'-';
 
  551     perm += fi.permission( QFile::ExeOwner ) ? 
'x' : 
'-';
 
  553     perm += fi.permission( QFile::ReadGroup ) ? 
'r' : 
'-';
 
  554     perm += fi.permission( QFile::WriteGroup ) ? 
'w' : 
'-';
 
  555     perm += fi.permission( QFile::ExeGroup ) ? 
'x' : 
'-';
 
  556     perm += fi.permission( QFile::ReadOther ) ? 
'r' : 
'-';
 
  557     perm += fi.permission( QFile::WriteOther ) ? 
'w' : 
'-';
 
  558     perm += fi.permission( QFile::ExeOther ) ? 
'x' : 
'-';
 
  566     if ( fi.isDir() && fi.isSymLink() )
 
  568       type = tr( 
"folder" );
 
  571     else if ( fi.isDir() )
 
  573       type = tr( 
"folder" );
 
  574       icon = iconDirectory;
 
  576     else if ( fi.isFile() && fi.isSymLink() )
 
  581     else if ( fi.isFile() )
 
  589     QTreeWidgetItem *item = 
new QTreeWidgetItem( texts );
 
  590     item->setIcon( 0, icon );
 
  594   addTopLevelItems( items );
 
  597   QgsSettings settings;
 
  598   QList<QVariant> lst = settings.value( QStringLiteral( 
"dataitem/directoryHiddenColumns" ) ).toList();
 
  599   const auto constLst = lst;
 
  600   for ( 
const QVariant &colVariant : constLst )
 
  602     setColumnHidden( colVariant.toInt(), 
true );
 
  608   if ( event->button() == Qt::RightButton )
 
  614     labels << tr( 
"Name" ) << tr( 
"Size" ) << tr( 
"Date" ) << tr( 
"Permissions" ) << tr( 
"Owner" ) << tr( 
"Group" ) << tr( 
"Type" );
 
  615     for ( 
int i = 0; i < labels.count(); i++ )
 
  618       action->setObjectName( QString::number( i ) );
 
  619       action->setCheckable( 
true );
 
  620       action->setChecked( !isColumnHidden( i ) );
 
  623     popupMenu.exec( event->globalPos() );
 
  629   QAction *action = qobject_cast<QAction *>( sender() );
 
  633   int columnIndex = action->objectName().toInt();
 
  634   setColumnHidden( columnIndex, !isColumnHidden( columnIndex ) );
 
  637   QgsSettings settings;
 
  639   for ( 
int i = 0; i < columnCount(); i++ )
 
  641     if ( isColumnHidden( i ) )
 
  642       lst.append( QVariant( i ) );
 
  644   settings.setValue( QStringLiteral( 
"dataitem/directoryHiddenColumns" ), lst );
 
  652   : 
QgsDirectoryItem( parent, name, dirPath, path, QStringLiteral( 
"special:ProjectHome" ) )
 
  665   return QStringLiteral( 
" 1" );
 
BrowserItemState
Browser item states.
@ NotPopulated
Children not yet created.
@ Populating
Creating children in separate thread (populating or refreshing)
@ Populated
Children created.
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.
@ 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)
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.
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).
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.
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.
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 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.