Skip to content

Commit 9d82df5

Browse files
committedOct 13, 2018
Forward to app blocking/unblocking of attr table updates
Fixes #20094 - Extracting z-coordinates takes ages and makes the system unresponsive
1 parent afc873d commit 9d82df5

File tree

7 files changed

+103
-9
lines changed

7 files changed

+103
-9
lines changed
 

‎python/core/auto_generated/qgsapplication.sip.in

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -824,6 +824,21 @@ Emits the signal to collect all the strings of .qgs to be included in ts file
824824
.. versionadded:: 3.4
825825
%End
826826

827+
void blockAttributeTableUpdates( const QgsVectorLayer *layer );
828+
%Docstring
829+
Emits the signal to block updates for attribute tables connected a particular ``layer``
830+
831+
.. versionadded:: 3.4
832+
%End
833+
834+
void unblockAttributeTableUpdates( const QgsVectorLayer *layer );
835+
%Docstring
836+
Emits the signal to unblock updates for attribute tables connected a particular ``layer``
837+
838+
.. versionadded:: 3.4
839+
%End
840+
841+
827842
%If (ANDROID)
828843
//dummy method to workaround sip generation issue
829844
bool x11EventFilter( XEvent *event );
@@ -852,6 +867,21 @@ In order to register translatable strings, connect to this signal and register t
852867
.. versionadded:: 3.4
853868
%End
854869

870+
void attributeTableUpdateBlocked( const QgsVectorLayer *layer );
871+
%Docstring
872+
Emitted when attribute table updates for a particular ``layer`` must be blocked
873+
874+
.. versionadded:: 3.4
875+
%End
876+
877+
void attributeTableUpdateUnblocked( const QgsVectorLayer *layer );
878+
%Docstring
879+
Emitted when all attribute table updates for a particular ``layer`` must be unblocked
880+
881+
.. versionadded:: 3.4
882+
%End
883+
884+
855885
};
856886

857887

‎src/app/qgisapp.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7090,13 +7090,14 @@ void QgisApp::fieldCalculator()
70907090

70917091
void QgisApp::attributeTable( QgsAttributeTableFilterModel::FilterMode filter )
70927092
{
7093-
QgsVectorLayer *myLayer = qobject_cast<QgsVectorLayer *>( activeLayer() );
7094-
if ( !myLayer )
7093+
QgsVectorLayer *vectorLayer = qobject_cast<QgsVectorLayer *>( activeLayer() );
7094+
if ( !vectorLayer )
70957095
{
70967096
return;
70977097
}
70987098

7099-
QgsAttributeTableDialog *mDialog = new QgsAttributeTableDialog( myLayer, filter );
7099+
QgsAttributeTableDialog *mDialog = new QgsAttributeTableDialog( vectorLayer, filter );
7100+
71007101
mDialog->show();
71017102
// the dialog will be deleted by itself on close
71027103
}

‎src/app/qgsattributetabledialog.cpp

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,18 @@ QgsAttributeTableDialog::QgsAttributeTableDialog( QgsVectorLayer *layer, QgsAttr
111111
connect( mActionExpressionSelect, &QAction::triggered, this, &QgsAttributeTableDialog::mActionExpressionSelect_triggered );
112112
connect( mMainView, &QgsDualView::showContextMenuExternally, this, &QgsAttributeTableDialog::showContextMenu );
113113

114+
// Block/unblock table updates (feature cache signals)
115+
connect( QgsApplication::instance(), &QgsApplication::attributeTableUpdateBlocked, [ = ]( const QgsVectorLayer * layer )
116+
{
117+
if ( layer == mLayer )
118+
this->blockCacheUpdateSignals( true );
119+
} );
120+
connect( QgsApplication::instance(), &QgsApplication::attributeTableUpdateUnblocked, [ = ]( const QgsVectorLayer * layer )
121+
{
122+
if ( layer == mLayer )
123+
this->blockCacheUpdateSignals( false );
124+
} );
125+
114126
const QgsFields fields = mLayer->fields();
115127
for ( const QgsField &field : fields )
116128
{
@@ -715,20 +727,14 @@ void QgsAttributeTableDialog::mActionOpenFieldCalculator_triggered()
715727
QgsAttributeTableModel *masterModel = mMainView->masterModel();
716728

717729
QgsFieldCalculator calc( mLayer, this );
718-
masterModel->layerCache()->blockSignals( true );
719730
if ( calc.exec() == QDialog::Accepted )
720731
{
721-
masterModel->layerCache()->blockSignals( false );
722732
int col = masterModel->fieldCol( calc.changedAttributeId() );
723733
if ( col >= 0 )
724734
{
725735
masterModel->reload( masterModel->index( 0, col ), masterModel->index( masterModel->rowCount() - 1, col ) );
726736
}
727737
}
728-
else
729-
{
730-
masterModel->layerCache()->blockSignals( false );
731-
}
732738
}
733739

734740
void QgsAttributeTableDialog::mActionSaveEdits_triggered()
@@ -1135,6 +1141,15 @@ void QgsAttributeTableDialog::setFilterExpression( const QString &filterString,
11351141
mMainView->setFilterMode( QgsAttributeTableFilterModel::ShowFilteredList );
11361142
}
11371143

1144+
void QgsAttributeTableDialog::blockCacheUpdateSignals( const bool block )
1145+
{
1146+
QgsAttributeTableModel *masterModel = mMainView->masterModel();
1147+
1148+
if ( ! masterModel )
1149+
return;
1150+
1151+
masterModel->layerCache()->blockSignals( block );
1152+
}
11381153

11391154
void QgsAttributeTableDialog::deleteFeature( const QgsFeatureId fid )
11401155
{

‎src/app/qgsattributetabledialog.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,7 @@ class APP_EXPORT QgsAttributeTableDialog : public QDialog, private Ui::QgsAttrib
242242

243243
void updateMultiEditButtonState();
244244
void deleteFeature( QgsFeatureId fid );
245+
void blockCacheUpdateSignals( const bool block );
245246

246247
friend class TestQgsAttributeTable;
247248
};

‎src/app/qgsfieldcalculator.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,10 @@ void QgsFieldCalculator::accept()
267267
return;
268268
}
269269

270+
// Begin feature modifications, block updates for attr tables
271+
// connected to this layer
272+
QgsApplication::instance()->blockAttributeTableUpdates( mVectorLayer );
273+
270274
//go through all the features and change the new attribute
271275
QgsFeature feature;
272276
bool calculationSuccess = true;
@@ -317,6 +321,8 @@ void QgsFieldCalculator::accept()
317321
rownum++;
318322
}
319323

324+
QgsApplication::instance()->unblockAttributeTableUpdates( mVectorLayer );
325+
320326
QApplication::restoreOverrideCursor();
321327

322328
if ( !calculationSuccess )

‎src/core/qgsapplication.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1535,6 +1535,16 @@ void QgsApplication::collectTranslatableObjects( QgsTranslationContext *translat
15351535
emit requestForTranslatableObjects( translationContext );
15361536
}
15371537

1538+
void QgsApplication::unblockAttributeTableUpdates( const QgsVectorLayer *layer )
1539+
{
1540+
emit attributeTableUpdateUnblocked( layer );
1541+
}
1542+
1543+
void QgsApplication::blockAttributeTableUpdates( const QgsVectorLayer *layer )
1544+
{
1545+
emit attributeTableUpdateBlocked( layer );
1546+
}
1547+
15381548
QString QgsApplication::nullRepresentation()
15391549
{
15401550
ApplicationMembers *appMembers = members();

‎src/core/qgsapplication.h

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ class QgsLayoutItemRegistry;
4949
class QgsAuthManager;
5050
class QgsNetworkContentFetcherRegistry;
5151
class QTranslator;
52+
class QgsVectorLayer;
5253

5354
/**
5455
* \ingroup core
@@ -757,6 +758,21 @@ class CORE_EXPORT QgsApplication : public QApplication
757758
*/
758759
void collectTranslatableObjects( QgsTranslationContext *translationContext );
759760

761+
/**
762+
* Emits the signal to block updates for attribute tables connected a particular \a layer
763+
*
764+
* \since QGIS 3.4
765+
*/
766+
void blockAttributeTableUpdates( const QgsVectorLayer *layer );
767+
768+
/**
769+
* Emits the signal to unblock updates for attribute tables connected a particular \a layer
770+
*
771+
* \since QGIS 3.4
772+
*/
773+
void unblockAttributeTableUpdates( const QgsVectorLayer *layer );
774+
775+
760776
#ifdef SIP_RUN
761777
SIP_IF_FEATURE( ANDROID )
762778
//dummy method to workaround sip generation issue
@@ -788,6 +804,21 @@ class CORE_EXPORT QgsApplication : public QApplication
788804
*/
789805
void requestForTranslatableObjects( QgsTranslationContext *translationContext );
790806

807+
/**
808+
* Emitted when attribute table updates for a particular \a layer must be blocked
809+
*
810+
* \since QGIS 3.4
811+
*/
812+
void attributeTableUpdateBlocked( const QgsVectorLayer *layer );
813+
814+
/**
815+
* Emitted when all attribute table updates for a particular \a layer must be unblocked
816+
*
817+
* \since QGIS 3.4
818+
*/
819+
void attributeTableUpdateUnblocked( const QgsVectorLayer *layer );
820+
821+
791822
private:
792823

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

1 commit comments

Comments
 (1)

nyalldawson commented on Oct 13, 2018

@nyalldawson
Collaborator

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

Please sign in to comment.