Skip to content

Commit

Permalink
[browser] Add global option to disable monitoring of directories
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
nyalldawson committed Jun 1, 2021
1 parent 22cc4da commit c8004cb
Show file tree
Hide file tree
Showing 9 changed files with 108 additions and 43 deletions.
2 changes: 1 addition & 1 deletion python/core/auto_generated/browser/qgsdirectoryitem.sip.in
Expand Up @@ -181,6 +181,7 @@ This is a persistent setting, which is saved in QSettings.
.. versionadded:: 3.20
%End


public slots:
virtual void childrenCreated();

Expand All @@ -190,7 +191,6 @@ This is a persistent setting, which is saved in QSettings.
void init();



};


Expand Down
5 changes: 5 additions & 0 deletions resources/qgis_global_settings.ini
Expand Up @@ -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

Expand Down
4 changes: 4 additions & 0 deletions src/app/options/qgsoptions.cpp
Expand Up @@ -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() );

Expand Down Expand Up @@ -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() );
Expand Down
24 changes: 11 additions & 13 deletions src/core/browser/qgsdirectoryitem.cpp
Expand Up @@ -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();
}

Expand All @@ -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 );
Expand All @@ -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()
Expand Down Expand Up @@ -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()
Expand Down
16 changes: 8 additions & 8 deletions src/core/browser/qgsdirectoryitem.h
Expand Up @@ -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.
*
Expand All @@ -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:
Expand All @@ -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;

Expand Down
27 changes: 27 additions & 0 deletions src/gui/qgsbrowserdockwidget.cpp
Expand Up @@ -47,6 +47,7 @@
#include "qgsmapcanvas.h"

#include <QDragEnterEvent>
#include <functional>

QgsBrowserDockWidget::QgsBrowserDockWidget( const QString &name, QgsBrowserGuiModel *browserModel, QWidget *parent )
: QgsDockWidget( parent )
Expand Down Expand Up @@ -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()
Expand Down Expand Up @@ -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 ) );
Expand Down
1 change: 1 addition & 0 deletions src/gui/qgsbrowserdockwidget.h
Expand Up @@ -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
Expand Down
55 changes: 34 additions & 21 deletions src/ui/qgsoptionsbase.ui
Expand Up @@ -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"/>
Expand All @@ -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">
Expand All @@ -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">
Expand All @@ -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>
Expand Down Expand Up @@ -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>
Expand Down Expand Up @@ -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"/>
Expand Down
17 changes: 17 additions & 0 deletions tests/src/core/testqgsdataitem.cpp
Expand Up @@ -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...
Expand Down Expand Up @@ -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()
Expand Down

0 comments on commit c8004cb

Please sign in to comment.