[browser] Add global option to disable monitoring of directories

Allows users to manually opt-out of monitoring directories in
the browser by default, and also provides a mechanism for
enterprise installs to disable this potentially unwanted behavior.
This commit is contained in:
Nyall Dawson 2021-05-31 14:32:41 +10:00
parent 22cc4da6e9
commit c8004cb3c6
9 changed files with 108 additions and 43 deletions

View File

@ -181,6 +181,7 @@ This is a persistent setting, which is saved in QSettings.
.. versionadded:: 3.20
%End
public slots:
virtual void childrenCreated();
@ -190,7 +191,6 @@ This is a persistent setting, which is saved in QSettings.
void init();
};

View File

@ -14,6 +14,11 @@ allowVersionCheck=true
# If true, added layer names will be automatically capitalized and underscores replaced with spaces
formatLayerName=false
# If set to true then directories will be automatically monitored and refreshed when their contents change outside of QGIS.
# This monitoring can be expensive, especially for remote or network drives, in which case setting this option to false
# can result in a speedup of the QGIS interface.
monitorDirectoriesInBrowser=true
# Snapping enabled by default
digitizing\default_snap_enabled=false

View File

@ -475,6 +475,8 @@ QgsOptions::QgsOptions( QWidget *parent, Qt::WindowFlags fl, const QList<QgsOpti
if ( index == -1 ) index = 1;
cmbScanZipInBrowser->setCurrentIndex( index );
mCheckMonitorDirectories->setChecked( mSettings->value( QStringLiteral( "/qgis/monitorDirectoriesInBrowser" ), true ).toBool() );
// log rendering events, for userspace debugging
mLogCanvasRefreshChkBx->setChecked( QgsMapRendererJob::settingsLogCanvasRefreshEvent.value() );
@ -1584,6 +1586,8 @@ void QgsOptions::saveOptions()
cmbScanItemsInBrowser->currentData().toString() );
mSettings->setValue( QStringLiteral( "/qgis/scanZipInBrowser2" ),
cmbScanZipInBrowser->currentData().toString() );
mSettings->setValue( QStringLiteral( "/qgis/monitorDirectoriesInBrowser" ), mCheckMonitorDirectories->isChecked() );
mSettings->setValue( QStringLiteral( "/qgis/mainSnappingWidgetMode" ), mSnappingMainDialogComboBox->currentData() );
mSettings->setValue( QStringLiteral( "/qgis/legendsymbolMinimumSize" ), mLegendSymbolMinimumSizeSpinBox->value() );

View File

@ -38,9 +38,7 @@
QgsDirectoryItem::QgsDirectoryItem( QgsDataItem *parent, const QString &name, const QString &path )
: QgsDataCollectionItem( parent, QDir::toNativeSeparators( name ), path )
, mDirPath( path )
, mRefreshLater( false )
{
mType = Qgis::BrowserItemType::Directory;
init();
}
@ -49,8 +47,15 @@ QgsDirectoryItem::QgsDirectoryItem( QgsDataItem *parent, const QString &name,
const QString &providerKey )
: QgsDataCollectionItem( parent, QDir::toNativeSeparators( name ), path, providerKey )
, mDirPath( dirPath )
, mRefreshLater( false )
{
init();
}
void QgsDirectoryItem::init()
{
mType = Qgis::BrowserItemType::Directory;
setToolTip( QDir::toNativeSeparators( mDirPath ) );
QgsSettings settings;
mMonitoring = monitoringForPath( mDirPath );
@ -76,14 +81,6 @@ QgsDirectoryItem::QgsDirectoryItem( QgsDataItem *parent, const QString &name,
mIconColor = QColor( colorString );
}
settings.endGroup();
mType = Qgis::BrowserItemType::Directory;
init();
}
void QgsDirectoryItem::init()
{
setToolTip( QDir::toNativeSeparators( mDirPath ) );
}
void QgsDirectoryItem::reevaluateMonitoring()
@ -455,8 +452,9 @@ bool QgsDirectoryItem::pathShouldByMonitoredByDefault( const QString &path )
if ( QgsFileUtils::pathIsSlowDevice( path ) )
return false;
// paths are monitored by default if no explicit setting is in place
return true;
// paths are monitored by default if no explicit setting is in place, and the user hasn't
// completely opted out of all browser monitoring
return QgsSettings().value( QStringLiteral( "/qgis/monitorDirectoriesInBrowser" ), true ).toBool();
}
void QgsDirectoryItem::childrenCreated()

View File

@ -186,13 +186,6 @@ class CORE_EXPORT QgsDirectoryItem : public QgsDataCollectionItem
*/
void setMonitoring( Qgis::BrowserDirectoryMonitoring monitoring );
public slots:
void childrenCreated() override;
void directoryChanged();
protected:
void init();
/**
* Re-evaluate whether the directory item should be monitored for changes.
*
@ -202,6 +195,13 @@ class CORE_EXPORT QgsDirectoryItem : public QgsDataCollectionItem
*/
void reevaluateMonitoring() SIP_SKIP;
public slots:
void childrenCreated() override;
void directoryChanged();
protected:
void init();
QString mDirPath;
private:
@ -211,7 +211,7 @@ class CORE_EXPORT QgsDirectoryItem : public QgsDataCollectionItem
Qgis::BrowserDirectoryMonitoring mMonitoring = Qgis::BrowserDirectoryMonitoring::Default;
bool mMonitored = true;
QFileSystemWatcher *mFileSystemWatcher = nullptr;
bool mRefreshLater;
bool mRefreshLater = false;
QDateTime mLastScan;
QColor mIconColor;

View File

@ -47,6 +47,7 @@
#include "qgsmapcanvas.h"
#include <QDragEnterEvent>
#include <functional>
QgsBrowserDockWidget::QgsBrowserDockWidget( const QString &name, QgsBrowserGuiModel *browserModel, QWidget *parent )
: QgsDockWidget( parent )
@ -109,6 +110,8 @@ QgsBrowserDockWidget::QgsBrowserDockWidget( const QString &name, QgsBrowserGuiMo
connect( mBrowserView, &QgsDockBrowserTreeView::customContextMenuRequested, this, &QgsBrowserDockWidget::showContextMenu );
connect( mBrowserView, &QgsDockBrowserTreeView::doubleClicked, this, &QgsBrowserDockWidget::itemDoubleClicked );
connect( mSplitter, &QSplitter::splitterMoved, this, &QgsBrowserDockWidget::splitterMoved );
connect( QgsGui::instance(), &QgsGui::optionsChanged, this, &QgsBrowserDockWidget::onOptionsChanged );
}
QgsBrowserDockWidget::~QgsBrowserDockWidget()
@ -194,6 +197,30 @@ void QgsBrowserDockWidget::itemDoubleClicked( const QModelIndex &index )
}
}
void QgsBrowserDockWidget::onOptionsChanged()
{
std::function< void( const QModelIndex &index ) > updateItem;
updateItem = [this, &updateItem]( const QModelIndex & index )
{
if ( QgsDirectoryItem *dirItem = qobject_cast< QgsDirectoryItem * >( mModel->dataItem( index ) ) )
{
dirItem->reevaluateMonitoring();
}
const int rowCount = mModel->rowCount( index );
for ( int i = 0; i < rowCount; ++i )
{
const QModelIndex child = mModel->index( i, 0, index );
updateItem( child );
}
};
for ( int i = 0; i < mModel->rowCount(); ++i )
{
updateItem( mModel->index( i, 0 ) );
}
}
void QgsBrowserDockWidget::showContextMenu( QPoint pt )
{
QModelIndex index = mProxyModel->mapToSource( mBrowserView->indexAt( pt ) );

View File

@ -178,6 +178,7 @@ class GUI_EXPORT QgsBrowserDockWidget : public QgsDockWidget, private Ui::QgsBro
private slots:
void itemDoubleClicked( const QModelIndex &index );
void onOptionsChanged();
private:
//! Refresh the model

View File

@ -2136,25 +2136,8 @@
<string>Data Source Handling</string>
</property>
<layout class="QGridLayout" name="gridLayout_23" columnstretch="0,0,0">
<item row="2" column="0">
<widget class="QLabel" name="textLabel1_13">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Prompt for sublayers when opening</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_30">
<property name="text">
<string>Scan for valid items in the browser dock</string>
</property>
</widget>
<item row="1" column="2">
<widget class="QComboBox" name="cmbScanZipInBrowser"/>
</item>
<item row="0" column="2">
<widget class="QComboBox" name="cmbScanItemsInBrowser"/>
@ -2168,6 +2151,13 @@
</item>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_30">
<property name="text">
<string>Scan for valid items in the browser dock</string>
</property>
</widget>
</item>
<item row="1" column="1">
<spacer name="horizontalSpacer_3">
<property name="orientation">
@ -2181,8 +2171,18 @@
</property>
</spacer>
</item>
<item row="1" column="2">
<widget class="QComboBox" name="cmbScanZipInBrowser"/>
<item row="2" column="0">
<widget class="QLabel" name="textLabel1_13">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Prompt for sublayers when opening</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_29">
@ -2191,6 +2191,13 @@
</property>
</widget>
</item>
<item row="3" column="0" colspan="3">
<widget class="QCheckBox" name="mCheckMonitorDirectories">
<property name="text">
<string>Automatically refresh directories in browser dock when their contents change</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
@ -6338,6 +6345,7 @@ p, li { white-space: pre-wrap; }
<tabstop>cmbScanItemsInBrowser</tabstop>
<tabstop>cmbScanZipInBrowser</tabstop>
<tabstop>cmbPromptSublayers</tabstop>
<tabstop>mCheckMonitorDirectories</tabstop>
<tabstop>mLocalizedDataPathAddButton</tabstop>
<tabstop>mLocalizedDataPathRemoveButton</tabstop>
<tabstop>mLocalizedDataPathUpButton</tabstop>
@ -6484,6 +6492,11 @@ p, li { white-space: pre-wrap; }
<tabstop>mOpenClDevicesCombo</tabstop>
<tabstop>mGPUInfoTextBrowser</tabstop>
<tabstop>mCbEarlyResampling</tabstop>
<tabstop>mCrsAccuracySpin</tabstop>
<tabstop>mCrsAccuracyIndicatorCheck</tabstop>
<tabstop>mLegendSymbolMinimumSizeSpinBox</tabstop>
<tabstop>mLegendSymbolMaximumSizeSpinBox</tabstop>
<tabstop>mDefaultMValueSpinBox</tabstop>
</tabstops>
<resources>
<include location="../../images/images.qrc"/>

View File

@ -85,6 +85,7 @@ void TestQgsDataItem::initTestCase()
QCoreApplication::setApplicationName( QStringLiteral( "QGIS-TEST" ) );
// save current scanItemsSetting value
QgsSettings settings;
settings.clear();
mScanItemsSetting = settings.value( QStringLiteral( "/qgis/scanItemsInBrowser2" ), QVariant( "" ) ).toString();
//create a directory item that will be used in all tests...
@ -340,6 +341,22 @@ void TestQgsDataItem::testDirItemMonitoring()
QCOMPARE( childItem3->monitoring(), Qgis::BrowserDirectoryMonitoring::NeverMonitor );
QVERIFY( !childItem3->isMonitored() );
QVERIFY( !childItem3->mFileSystemWatcher );
// turn off monitoring
QgsSettings().setValue( QStringLiteral( "/qgis/monitorDirectoriesInBrowser" ), false );
dirItem->reevaluateMonitoring();
QVERIFY( !dirItem->isMonitored() );
QVERIFY( !dirItem->mFileSystemWatcher );
QCOMPARE( childItem1->monitoring(), Qgis::BrowserDirectoryMonitoring::Default );
QVERIFY( !childItem1->isMonitored() );
QVERIFY( !childItem1->mFileSystemWatcher );
QCOMPARE( childItem2->monitoring(), Qgis::BrowserDirectoryMonitoring::AlwaysMonitor );
QVERIFY( childItem2->isMonitored() );
QVERIFY( childItem2->mFileSystemWatcher );
QCOMPARE( childItem3->monitoring(), Qgis::BrowserDirectoryMonitoring::NeverMonitor );
QVERIFY( !childItem3->isMonitored() );
QVERIFY( !childItem3->mFileSystemWatcher );
QgsSettings().setValue( QStringLiteral( "/qgis/monitorDirectoriesInBrowser" ), true );
}
void TestQgsDataItem::testDirItemMonitoringSlowDrive()