Skip to content
Permalink
Browse files

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.
  • Loading branch information
elpaso committed Aug 8, 2017
1 parent a2d4e82 commit bcb48f2bdc8f274cbc68f376489430f45e0b17d1
Showing with 18 additions and 2 deletions.
  1. +1 −0 python/core/qgsdataitem.sip
  2. +16 −2 src/core/qgsdataitem.cpp
  3. +1 −0 src/core/qgsdataitem.h
@@ -525,6 +525,7 @@ Check if the given path is hidden from the browser model
:rtype: bool
%End


public slots:
virtual void childrenCreated();
void directoryChanged();
@@ -238,6 +238,7 @@ void QgsDataItem::populate( bool foreground )
{
mFutureWatcher = new QFutureWatcher< QVector <QgsDataItem *> >( this );
}

connect( mFutureWatcher, &QFutureWatcherBase::finished, this, &QgsDataItem::childrenCreated );
mFutureWatcher->setFuture( QtConcurrent::run( runCreateChildren, this ) );
}
@@ -791,12 +792,22 @@ void QgsDirectoryItem::directoryChanged()
{
if ( state() == Populating )
{
// schedule to refresh later, because refres() simply returns if Populating
// schedule to refresh later, because refresh() simply returns if Populating
mRefreshLater = true;
}
else
{
refresh();
// We definintely don't want the temporary files created by sqlite
// to re-trigger a refresh in an infinite loop.
disconnect( mFileSystemWatcher, &QFileSystemWatcher::directoryChanged, this, &QgsDirectoryItem::directoryChanged );
// QFileSystemWhatcher::directoryChanged is emitted when a
// file is created and not when it is closed/flushed.
//
// Delay to give to OS the time to complete writing the file
// this happens when a new file appears in the directory and
// the item's children thread will try to open the file with
// GDAL or OGR even if it is still being written.
QTimer::singleShot( 100, this, SLOT( refresh() ) );
}
}

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


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

bool QgsDirectoryItem::equal( const QgsDataItem *other )
@@ -468,6 +468,7 @@ class CORE_EXPORT QgsDirectoryItem : public QgsDataCollectionItem
//! Check if the given path is hidden from the browser model
static bool hiddenPath( const QString &path );


public slots:
virtual void childrenCreated() override;
void directoryChanged();

0 comments on commit bcb48f2

Please sign in to comment.
You can’t perform that action at this time.