Skip to content

Commit

Permalink
Forward to app blocking/unblocking of attr table updates
Browse files Browse the repository at this point in the history
Fixes #20094 - Extracting z-coordinates takes ages and makes the system unresponsive
  • Loading branch information
elpaso committed Oct 13, 2018
1 parent afc873d commit 9d82df5
Show file tree
Hide file tree
Showing 7 changed files with 103 additions and 9 deletions.
30 changes: 30 additions & 0 deletions python/core/auto_generated/qgsapplication.sip.in
Original file line number Diff line number Diff line change
Expand Up @@ -824,6 +824,21 @@ Emits the signal to collect all the strings of .qgs to be included in ts file
.. versionadded:: 3.4
%End

void blockAttributeTableUpdates( const QgsVectorLayer *layer );
%Docstring
Emits the signal to block updates for attribute tables connected a particular ``layer``

.. versionadded:: 3.4
%End

void unblockAttributeTableUpdates( const QgsVectorLayer *layer );
%Docstring
Emits the signal to unblock updates for attribute tables connected a particular ``layer``

.. versionadded:: 3.4
%End


%If (ANDROID)
//dummy method to workaround sip generation issue
bool x11EventFilter( XEvent *event );
Expand Down Expand Up @@ -852,6 +867,21 @@ In order to register translatable strings, connect to this signal and register t
.. versionadded:: 3.4
%End

void attributeTableUpdateBlocked( const QgsVectorLayer *layer );
%Docstring
Emitted when attribute table updates for a particular ``layer`` must be blocked

.. versionadded:: 3.4
%End

void attributeTableUpdateUnblocked( const QgsVectorLayer *layer );
%Docstring
Emitted when all attribute table updates for a particular ``layer`` must be unblocked

.. versionadded:: 3.4
%End


};


Expand Down
7 changes: 4 additions & 3 deletions src/app/qgisapp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7090,13 +7090,14 @@ void QgisApp::fieldCalculator()

void QgisApp::attributeTable( QgsAttributeTableFilterModel::FilterMode filter )
{
QgsVectorLayer *myLayer = qobject_cast<QgsVectorLayer *>( activeLayer() );
if ( !myLayer )
QgsVectorLayer *vectorLayer = qobject_cast<QgsVectorLayer *>( activeLayer() );
if ( !vectorLayer )
{
return;
}

QgsAttributeTableDialog *mDialog = new QgsAttributeTableDialog( myLayer, filter );
QgsAttributeTableDialog *mDialog = new QgsAttributeTableDialog( vectorLayer, filter );

mDialog->show();
// the dialog will be deleted by itself on close
}
Expand Down
27 changes: 21 additions & 6 deletions src/app/qgsattributetabledialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,18 @@ QgsAttributeTableDialog::QgsAttributeTableDialog( QgsVectorLayer *layer, QgsAttr
connect( mActionExpressionSelect, &QAction::triggered, this, &QgsAttributeTableDialog::mActionExpressionSelect_triggered );
connect( mMainView, &QgsDualView::showContextMenuExternally, this, &QgsAttributeTableDialog::showContextMenu );

// Block/unblock table updates (feature cache signals)
connect( QgsApplication::instance(), &QgsApplication::attributeTableUpdateBlocked, [ = ]( const QgsVectorLayer * layer )
{
if ( layer == mLayer )
this->blockCacheUpdateSignals( true );
} );
connect( QgsApplication::instance(), &QgsApplication::attributeTableUpdateUnblocked, [ = ]( const QgsVectorLayer * layer )
{
if ( layer == mLayer )
this->blockCacheUpdateSignals( false );
} );

const QgsFields fields = mLayer->fields();
for ( const QgsField &field : fields )
{
Expand Down Expand Up @@ -715,20 +727,14 @@ void QgsAttributeTableDialog::mActionOpenFieldCalculator_triggered()
QgsAttributeTableModel *masterModel = mMainView->masterModel();

QgsFieldCalculator calc( mLayer, this );
masterModel->layerCache()->blockSignals( true );
if ( calc.exec() == QDialog::Accepted )
{
masterModel->layerCache()->blockSignals( false );
int col = masterModel->fieldCol( calc.changedAttributeId() );
if ( col >= 0 )
{
masterModel->reload( masterModel->index( 0, col ), masterModel->index( masterModel->rowCount() - 1, col ) );
}
}
else
{
masterModel->layerCache()->blockSignals( false );
}
}

void QgsAttributeTableDialog::mActionSaveEdits_triggered()
Expand Down Expand Up @@ -1135,6 +1141,15 @@ void QgsAttributeTableDialog::setFilterExpression( const QString &filterString,
mMainView->setFilterMode( QgsAttributeTableFilterModel::ShowFilteredList );
}

void QgsAttributeTableDialog::blockCacheUpdateSignals( const bool block )
{
QgsAttributeTableModel *masterModel = mMainView->masterModel();

if ( ! masterModel )
return;

masterModel->layerCache()->blockSignals( block );
}

void QgsAttributeTableDialog::deleteFeature( const QgsFeatureId fid )
{
Expand Down
1 change: 1 addition & 0 deletions src/app/qgsattributetabledialog.h
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,7 @@ class APP_EXPORT QgsAttributeTableDialog : public QDialog, private Ui::QgsAttrib

void updateMultiEditButtonState();
void deleteFeature( QgsFeatureId fid );
void blockCacheUpdateSignals( const bool block );

friend class TestQgsAttributeTable;
};
Expand Down
6 changes: 6 additions & 0 deletions src/app/qgsfieldcalculator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,10 @@ void QgsFieldCalculator::accept()
return;
}

// Begin feature modifications, block updates for attr tables
// connected to this layer
QgsApplication::instance()->blockAttributeTableUpdates( mVectorLayer );

//go through all the features and change the new attribute
QgsFeature feature;
bool calculationSuccess = true;
Expand Down Expand Up @@ -317,6 +321,8 @@ void QgsFieldCalculator::accept()
rownum++;
}

QgsApplication::instance()->unblockAttributeTableUpdates( mVectorLayer );

QApplication::restoreOverrideCursor();

if ( !calculationSuccess )
Expand Down
10 changes: 10 additions & 0 deletions src/core/qgsapplication.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1535,6 +1535,16 @@ void QgsApplication::collectTranslatableObjects( QgsTranslationContext *translat
emit requestForTranslatableObjects( translationContext );
}

void QgsApplication::unblockAttributeTableUpdates( const QgsVectorLayer *layer )
{
emit attributeTableUpdateUnblocked( layer );
}

void QgsApplication::blockAttributeTableUpdates( const QgsVectorLayer *layer )
{
emit attributeTableUpdateBlocked( layer );
}

QString QgsApplication::nullRepresentation()
{
ApplicationMembers *appMembers = members();
Expand Down
31 changes: 31 additions & 0 deletions src/core/qgsapplication.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ class QgsLayoutItemRegistry;
class QgsAuthManager;
class QgsNetworkContentFetcherRegistry;
class QTranslator;
class QgsVectorLayer;

/**
* \ingroup core
Expand Down Expand Up @@ -757,6 +758,21 @@ class CORE_EXPORT QgsApplication : public QApplication
*/
void collectTranslatableObjects( QgsTranslationContext *translationContext );

/**
* Emits the signal to block updates for attribute tables connected a particular \a layer
*
* \since QGIS 3.4
*/
void blockAttributeTableUpdates( const QgsVectorLayer *layer );

/**
* Emits the signal to unblock updates for attribute tables connected a particular \a layer
*
* \since QGIS 3.4
*/
void unblockAttributeTableUpdates( const QgsVectorLayer *layer );


#ifdef SIP_RUN
SIP_IF_FEATURE( ANDROID )
//dummy method to workaround sip generation issue
Expand Down Expand Up @@ -788,6 +804,21 @@ class CORE_EXPORT QgsApplication : public QApplication
*/
void requestForTranslatableObjects( QgsTranslationContext *translationContext );

/**
* Emitted when attribute table updates for a particular \a layer must be blocked
*
* \since QGIS 3.4
*/
void attributeTableUpdateBlocked( const QgsVectorLayer *layer );

/**
* Emitted when all attribute table updates for a particular \a layer must be unblocked
*
* \since QGIS 3.4
*/
void attributeTableUpdateUnblocked( const QgsVectorLayer *layer );


private:

static void copyPath( const QString &src, const QString &dst );
Expand Down

1 comment on commit 9d82df5

@nyalldawson
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, not sure I explained this well. I meant QgisApp::instance, not QgsApplication::instance. But otherwise this looks good.

Please sign in to comment.