Skip to content

Commit bcb48f2

Browse files
committedAug 9, 2017
Fixes two issues with the browser refresh
1. endless loop when a sqlite-based layer is opened, and wal+shm files are created. This triggers a loop because the directoryChanged signal is emitted again and again ... This was the real blocker. 2. when a new files appears in a directory the directoryChanged is emitted and OGR/GDAL may fail to open the file because the file copy was not yet finished. This commit fixes 1 but the fix for 2 is only a best effort using a 100 ms timer: I could not find a definitive solution to this issue, a file could be legitimately opened in streaming mode and it will always triggers an error, there is apparently no way to get the QFileSystemWatcher emit a signal when new files are closed flusehd and not when they are just created.
1 parent a2d4e82 commit bcb48f2

File tree

3 files changed

+18
-2
lines changed

3 files changed

+18
-2
lines changed
 

‎python/core/qgsdataitem.sip

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -525,6 +525,7 @@ Check if the given path is hidden from the browser model
525525
:rtype: bool
526526
%End
527527

528+
528529
public slots:
529530
virtual void childrenCreated();
530531
void directoryChanged();

‎src/core/qgsdataitem.cpp

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,7 @@ void QgsDataItem::populate( bool foreground )
238238
{
239239
mFutureWatcher = new QFutureWatcher< QVector <QgsDataItem *> >( this );
240240
}
241+
241242
connect( mFutureWatcher, &QFutureWatcherBase::finished, this, &QgsDataItem::childrenCreated );
242243
mFutureWatcher->setFuture( QtConcurrent::run( runCreateChildren, this ) );
243244
}
@@ -791,12 +792,22 @@ void QgsDirectoryItem::directoryChanged()
791792
{
792793
if ( state() == Populating )
793794
{
794-
// schedule to refresh later, because refres() simply returns if Populating
795+
// schedule to refresh later, because refresh() simply returns if Populating
795796
mRefreshLater = true;
796797
}
797798
else
798799
{
799-
refresh();
800+
// We definintely don't want the temporary files created by sqlite
801+
// to re-trigger a refresh in an infinite loop.
802+
disconnect( mFileSystemWatcher, &QFileSystemWatcher::directoryChanged, this, &QgsDirectoryItem::directoryChanged );
803+
// QFileSystemWhatcher::directoryChanged is emitted when a
804+
// file is created and not when it is closed/flushed.
805+
//
806+
// Delay to give to OS the time to complete writing the file
807+
// this happens when a new file appears in the directory and
808+
// the item's children thread will try to open the file with
809+
// GDAL or OGR even if it is still being written.
810+
QTimer::singleShot( 100, this, SLOT( refresh() ) );
800811
}
801812
}
802813

@@ -809,6 +820,7 @@ bool QgsDirectoryItem::hiddenPath( const QString &path )
809820
return ( idx > -1 );
810821
}
811822

823+
812824
void QgsDirectoryItem::childrenCreated()
813825
{
814826
QgsDebugMsgLevel( QString( "mRefreshLater = %1" ).arg( mRefreshLater ), 3 );
@@ -824,6 +836,8 @@ void QgsDirectoryItem::childrenCreated()
824836
{
825837
QgsDataCollectionItem::childrenCreated();
826838
}
839+
// Re-connect the file watcher after all children have been created
840+
connect( mFileSystemWatcher, &QFileSystemWatcher::directoryChanged, this, &QgsDirectoryItem::directoryChanged );
827841
}
828842

829843
bool QgsDirectoryItem::equal( const QgsDataItem *other )

‎src/core/qgsdataitem.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -468,6 +468,7 @@ class CORE_EXPORT QgsDirectoryItem : public QgsDataCollectionItem
468468
//! Check if the given path is hidden from the browser model
469469
static bool hiddenPath( const QString &path );
470470

471+
471472
public slots:
472473
virtual void childrenCreated() override;
473474
void directoryChanged();

0 commit comments

Comments
 (0)
Please sign in to comment.