Skip to content
Permalink
Browse files
[attribute form] Significant speed boost when loading relation editor…
… widgets (#42906)
  • Loading branch information
nirvn committed Apr 23, 2021
1 parent 74552a5 commit 1db625b8c571f421c9ee3df7dfef1d8d448b47c5
Showing with 62 additions and 39 deletions.
  1. +38 −19 src/gui/attributetable/qgsdualview.cpp
  2. +7 −3 src/gui/attributetable/qgsdualview.h
  3. +17 −17 src/gui/qgsrelationeditorwidget.cpp
@@ -123,6 +123,9 @@ void QgsDualView::init( QgsVectorLayer *layer, QgsMapCanvas *mapCanvas, const Qg
if ( !layer )
return;

delete mAttributeForm;
mAttributeForm = nullptr;

mLayer = layer;
mEditorContext = context;

@@ -133,10 +136,28 @@ void QgsDualView::init( QgsVectorLayer *layer, QgsMapCanvas *mapCanvas, const Qg

mTableView->setModel( mFilterModel );
mFeatureListView->setModel( mFeatureListModel );
delete mAttributeForm;
mAttributeForm = new QgsAttributeForm( mLayer, mTempAttributeFormFeature, mEditorContext );
mTempAttributeFormFeature = QgsFeature();
if ( !context.parentContext() )

connect( mFilterModel, &QgsAttributeTableFilterModel::sortColumnChanged, this, &QgsDualView::onSortColumnChanged );

if ( mFeatureListPreviewButton->defaultAction() )
mFeatureListView->setDisplayExpression( mDisplayExpression );
else
columnBoxInit();

// This slows down load of the attribute table heaps and uses loads of memory.
//mTableView->resizeColumnsToContents();

if ( mFeatureListModel->rowCount( ) > 0 )
mFeatureListView->setEditSelection( QgsFeatureIds() << mFeatureListModel->data( mFeatureListModel->index( 0, 0 ), QgsFeatureListModel::Role::FeatureRole ).value<QgsFeature>().id() );

}

void QgsDualView::initAttributeForm( const QgsFeature &feature )
{
Q_ASSERT( !mAttributeForm );

mAttributeForm = new QgsAttributeForm( mLayer, feature, mEditorContext );
if ( !mEditorContext.parentContext() )
{
mAttributeEditorScrollArea = new QgsScrollArea();
mAttributeEditorScrollArea->setWidgetResizable( true );
@@ -169,19 +190,6 @@ void QgsDualView::init( QgsVectorLayer *layer, QgsMapCanvas *mapCanvas, const Qg
} );

connect( mMasterModel, &QgsAttributeTableModel::modelChanged, mAttributeForm, &QgsAttributeForm::refreshFeature );
connect( mFilterModel, &QgsAttributeTableFilterModel::sortColumnChanged, this, &QgsDualView::onSortColumnChanged );

if ( mFeatureListPreviewButton->defaultAction() )
mFeatureListView->setDisplayExpression( mDisplayExpression );
else
columnBoxInit();

// This slows down load of the attribute table heaps and uses loads of memory.
//mTableView->resizeColumnsToContents();

if ( mFeatureListModel->rowCount( ) > 0 )
mFeatureListView->setEditSelection( QgsFeatureIds() << mFeatureListModel->data( mFeatureListModel->index( 0, 0 ), QgsFeatureListModel::Role::FeatureRole ).value<QgsFeature>().id() );

}

void QgsDualView::columnBoxInit()
@@ -614,6 +622,9 @@ void QgsDualView::filterError( const QString &errorMessage )

void QgsDualView::featureListAboutToChangeEditSelection( bool &ok )
{
if ( !mAttributeForm )
return;

if ( mLayer->isEditable() && !mAttributeForm->save() )
ok = false;
}
@@ -622,7 +633,7 @@ void QgsDualView::featureListCurrentEditSelectionChanged( const QgsFeature &feat
{
if ( !mAttributeForm )
{
mTempAttributeFormFeature = feat;
initAttributeForm( feat );
}
else if ( !mLayer->isEditable() || mAttributeForm->save() )
{
@@ -649,7 +660,7 @@ void QgsDualView::setCurrentEditSelection( const QgsFeatureIds &fids )

bool QgsDualView::saveEditChanges()
{
return mAttributeForm->save();
return mAttributeForm ? mAttributeForm->save() : false;
}

void QgsDualView::openConditionalStyles()
@@ -659,19 +670,27 @@ void QgsDualView::openConditionalStyles()

void QgsDualView::setMultiEditEnabled( bool enabled )
{
if ( !mAttributeForm )
return;

if ( enabled )
{
mPreviousView = view();
setView( AttributeEditor );
}
else
{
setView( mPreviousView );
}

mAttributeForm->setMode( enabled ? QgsAttributeEditorContext::MultiEditMode : QgsAttributeEditorContext::SingleEditMode );
}

void QgsDualView::toggleSearchMode( bool enabled )
{
if ( !mAttributeForm )
return;

if ( enabled )
{
setView( AttributeEditor );
@@ -399,6 +399,13 @@ class GUI_EXPORT QgsDualView : public QStackedWidget, private Ui::QgsDualViewBas

private:

/**
* Initialize the attribute form to a given \a feature.
*
* \since QGIS 3.20
*/
void initAttributeForm( const QgsFeature &feature );

/**
* Initializes widgets which depend on the attributes of this layer
*/
@@ -435,9 +442,6 @@ class GUI_EXPORT QgsDualView : public QStackedWidget, private Ui::QgsDualViewBas
QString mDisplayExpression;
QgsAttributeTableConfig mConfig;
QgsScrollArea *mAttributeEditorScrollArea = nullptr;
// If the current feature is set, while the form is still not initialized
// we will temporarily save it in here and set it on init
QgsFeature mTempAttributeFormFeature;
QgsFeatureIds mLastFeatureSet;
bool mBrowsingAutoPanScaleAllowed = true;
ViewMode mPreviousView = AttributeTable;
@@ -201,11 +201,6 @@ QgsRelationEditorWidget::QgsRelationEditorWidget( const QVariantMap &config, QWi
mRelationLayout->setContentsMargins( 0, 0, 0, 0 );
topLayout->addLayout( mRelationLayout );

mDualView = new QgsDualView( this );
mDualView->setView( mViewMode );

mRelationLayout->addWidget( mDualView );

connect( mRootCollapsibleGroupBox, &QgsCollapsibleGroupBoxBasic::collapsedStateChanged, this, &QgsRelationEditorWidget::onCollapsedStateChanged );
connect( mViewModeButtonGroup, static_cast<void ( QButtonGroup::* )( int )>( &QButtonGroup::buttonClicked ),
this, static_cast<void ( QgsRelationEditorWidget::* )( int )>( &QgsRelationEditorWidget::setViewMode ) );
@@ -219,14 +214,20 @@ QgsRelationEditorWidget::QgsRelationEditorWidget( const QVariantMap &config, QWi
connect( mUnlinkFeatureButton, &QAbstractButton::clicked, this, &QgsRelationEditorWidget::unlinkSelectedFeatures );
connect( mZoomToFeatureButton, &QAbstractButton::clicked, this, &QgsRelationEditorWidget::zoomToSelectedFeatures );

connect( mDualView, &QgsDualView::showContextMenuExternally, this, &QgsRelationEditorWidget::showContextMenu );

// Set initial state for add/remove etc. buttons
updateButtons();
}

void QgsRelationEditorWidget::initDualView( QgsVectorLayer *layer, const QgsFeatureRequest &request )
{
if ( !mDualView )
{
mDualView = new QgsDualView( this );
mDualView->setView( mViewMode );
connect( mDualView, &QgsDualView::showContextMenuExternally, this, &QgsRelationEditorWidget::showContextMenu );
mRelationLayout->addWidget( mDualView );
}

QgsAttributeEditorContext ctx { mEditorContext };
ctx.setParentFormFeature( mFeature );
mDualView->init( layer, mEditorContext.mapCanvas(), request, ctx );
@@ -369,8 +370,11 @@ void QgsRelationEditorWidget::onCollapsedStateChanged( bool collapsed )
{
if ( !collapsed )
{
mVisible = true;
updateUi();
if ( !mVisible )
{
mVisible = true;
updateUi();
}
}
}

@@ -379,17 +383,14 @@ void QgsRelationEditorWidget::updateUi()
// If not yet initialized, it is not (yet) visible, so we don't load it to be faster (lazy loading)
// If it is already initialized, it has been set visible before and the currently shown feature is changing
// and the widget needs updating

if ( mVisible )
if ( mVisible && mRelation.isValid() && mFeature.isValid() )
{
QgsFeatureRequest myRequest = mRelation.getRelatedFeaturesRequest( mFeature );
QgsFeatureRequest request = mRelation.getRelatedFeaturesRequest( mFeature );

if ( mNmRelation.isValid() )
{
QgsFeatureIterator it = mRelation.referencingLayer()->getFeatures( myRequest );

QgsFeatureIterator it = mRelation.referencingLayer()->getFeatures( request );
QgsFeature fet;

QStringList filters;

while ( it.nextFeature( fet ) )
@@ -399,14 +400,13 @@ void QgsRelationEditorWidget::updateUi()
}

QgsFeatureRequest nmRequest;

nmRequest.setFilterExpression( filters.join( QLatin1String( " OR " ) ) );

initDualView( mNmRelation.referencedLayer(), nmRequest );
}
else if ( mRelation.referencingLayer() )
{
initDualView( mRelation.referencingLayer(), myRequest );
initDualView( mRelation.referencingLayer(), request );
}
}
}

0 comments on commit 1db625b

Please sign in to comment.