Skip to content

Commit c2129a8

Browse files
authoredMar 18, 2020
Merge pull request #35169 from troopa81/backport_33990_to_release_312
[Backport 3.12] Fixes crash when displaying relation editor
2 parents d1dbe73 + 67b5fd0 commit c2129a8

14 files changed

+75
-24
lines changed
 

‎python/gui/auto_generated/editorwidgets/qgsrelationreferencewidget.sip.in

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,14 @@ Returns the related feature foreign keys
7777
%End
7878

7979
void setEditorContext( const QgsAttributeEditorContext &context, QgsMapCanvas *canvas, QgsMessageBar *messageBar );
80+
%Docstring
81+
Sets the editor ``context``
82+
83+
.. note::
84+
85+
if context cadDockWidget is null, it won't be possible to digitize
86+
the geometry of a referenced feature from this widget
87+
%End
8088

8189
bool embedForm();
8290
%Docstring

‎python/gui/auto_generated/qgsrelationeditorwidget.sip.in

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,14 @@ inserting and deleting entries on the intermediate table as required.
6666
void setFeature( const QgsFeature &feature );
6767

6868
void setEditorContext( const QgsAttributeEditorContext &context );
69+
%Docstring
70+
Sets the editor ``context``
71+
72+
.. note::
73+
74+
if context cadDockWidget is null, it won't be possible to digitize
75+
the geometry of a referencing feature from this widget
76+
%End
6977

7078
QgsIFeatureSelectionManager *featureSelectionManager();
7179
%Docstring

‎src/app/qgisapp.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9291,7 +9291,7 @@ void QgisApp::modifyAttributesOfSelectedFeatures()
92919291

92929292
//dummy feature
92939293
QgsFeature f;
9294-
QgsAttributeEditorContext context;
9294+
QgsAttributeEditorContext context( createAttributeEditorContext() );
92959295
context.setAllowCustomUi( false );
92969296

92979297
QgsAttributeDialog *dialog = new QgsAttributeDialog( vl, &f, false, this, true, context );
@@ -15501,3 +15501,13 @@ void QgisApp::triggerCrashHandler()
1550115501
RaiseException( 0x12345678, 0, 0, nullptr );
1550215502
#endif
1550315503
}
15504+
15505+
QgsAttributeEditorContext QgisApp::createAttributeEditorContext()
15506+
{
15507+
QgsAttributeEditorContext context;
15508+
context.setVectorLayerTools( vectorLayerTools() );
15509+
context.setMapCanvas( mapCanvas() );
15510+
context.setCadDockWidget( cadDockWidget() );
15511+
context.setMainMessageBar( messageBar() );
15512+
return context;
15513+
}

‎src/app/qgisapp.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1102,6 +1102,12 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow
11021102
//! Create a new spatial bookmark
11031103
void newBookmark( bool inProject = false );
11041104

1105+
/**
1106+
* Creates a default attribute editor context using the main map canvas and the main edit tools and message bar
1107+
* \since QGIS 3.12
1108+
*/
1109+
QgsAttributeEditorContext createAttributeEditorContext();
1110+
11051111
protected:
11061112

11071113
//! Handle state changes (WindowTitleChange)

‎src/app/qgisappinterface.cpp

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -755,11 +755,8 @@ QgsAttributeDialog *QgisAppInterface::getFeatureForm( QgsVectorLayer *l, QgsFeat
755755
myDa.setSourceCrs( l->crs(), QgsProject::instance()->transformContext() );
756756
myDa.setEllipsoid( QgsProject::instance()->ellipsoid() );
757757

758-
QgsAttributeEditorContext context;
758+
QgsAttributeEditorContext context( QgisApp::instance()->createAttributeEditorContext() );
759759
context.setDistanceArea( myDa );
760-
context.setVectorLayerTools( qgis->vectorLayerTools() );
761-
context.setMapCanvas( qgis->mapCanvas() );
762-
context.setCadDockWidget( qgis->cadDockWidget() );
763760
QgsAttributeDialog *dialog = new QgsAttributeDialog( l, &feature, false, qgis, true, context );
764761
if ( !feature.isValid() )
765762
{

‎src/app/qgsattributetabledialog.cpp

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -150,12 +150,9 @@ QgsAttributeTableDialog::QgsAttributeTableDialog( QgsVectorLayer *layer, QgsAttr
150150
QgsDistanceArea da;
151151
da.setSourceCrs( mLayer->crs(), QgsProject::instance()->transformContext() );
152152
da.setEllipsoid( QgsProject::instance()->ellipsoid() );
153-
mEditorContext.setDistanceArea( da );
154153

155-
mEditorContext.setVectorLayerTools( QgisApp::instance()->vectorLayerTools() );
156-
mEditorContext.setMapCanvas( QgisApp::instance()->mapCanvas() );
157-
mEditorContext.setMainMessageBar( QgisApp::instance()->messageBar() );
158-
mEditorContext.setCadDockWidget( QgisApp::instance()->cadDockWidget() );
154+
QgsAttributeEditorContext editorContext = QgisApp::instance()->createAttributeEditorContext();
155+
editorContext.setDistanceArea( da );
159156

160157
QgsFeatureRequest r;
161158
bool needsGeom = false;
@@ -175,12 +172,12 @@ QgsAttributeTableDialog::QgsAttributeTableDialog( QgsVectorLayer *layer, QgsAttr
175172
r.setFlags( QgsFeatureRequest::NoGeometry );
176173

177174
// Initialize dual view
178-
mMainView->init( mLayer, QgisApp::instance()->mapCanvas(), r, mEditorContext, false );
175+
mMainView->init( mLayer, QgisApp::instance()->mapCanvas(), r, editorContext, false );
179176

180177
QgsAttributeTableConfig config = mLayer->attributeTableConfig();
181178
mMainView->setAttributeTableConfig( config );
182179

183-
mFeatureFilterWidget->init( mLayer, mEditorContext, mMainView, QgisApp::instance()->messageBar(), QgisApp::instance()->messageTimeout() );
180+
mFeatureFilterWidget->init( mLayer, editorContext, mMainView, QgisApp::instance()->messageBar(), QgisApp::instance()->messageTimeout() );
184181

185182
mActionFeatureActions = new QToolButton();
186183
mActionFeatureActions->setAutoRaise( false );

‎src/app/qgsattributetabledialog.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,6 @@ class APP_EXPORT QgsAttributeTableDialog : public QDialog, private Ui::QgsAttrib
216216

217217
QPointer< QgsVectorLayer > mLayer = nullptr;
218218
QStringList mVisibleFields;
219-
QgsAttributeEditorContext mEditorContext;
220219

221220
void updateMultiEditButtonState();
222221
void deleteFeature( QgsFeatureId fid );

‎src/app/qgsfeatureaction.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,21 +53,19 @@ QgsAttributeDialog *QgsFeatureAction::newDialog( bool cloneFeature )
5353
{
5454
QgsFeature *f = cloneFeature ? new QgsFeature( *mFeature ) : mFeature;
5555

56-
QgsAttributeEditorContext context;
56+
QgsAttributeEditorContext context( QgisApp::instance()->createAttributeEditorContext() );
5757

5858
QgsDistanceArea myDa;
5959

6060
myDa.setSourceCrs( mLayer->crs(), QgsProject::instance()->transformContext() );
6161
myDa.setEllipsoid( QgsProject::instance()->ellipsoid() );
6262

6363
context.setDistanceArea( myDa );
64-
context.setVectorLayerTools( QgisApp::instance()->vectorLayerTools() );
65-
context.setMapCanvas( QgisApp::instance()->mapCanvas() );
66-
context.setCadDockWidget( QgisApp::instance()->cadDockWidget() );
6764
context.setFormMode( QgsAttributeEditorContext::StandaloneDialog );
6865

6966
QgsAttributeDialog *dialog = new QgsAttributeDialog( mLayer, f, cloneFeature, parentWidget(), true, context );
7067
dialog->setWindowFlags( dialog->windowFlags() | Qt::Tool );
68+
7169
dialog->setObjectName( QStringLiteral( "featureactiondlg:%1:%2" ).arg( mLayer->id() ).arg( f->id() ) );
7270

7371
QList<QgsAction> actions = mLayer->actions()->actions( QStringLiteral( "Feature" ) );

‎src/app/qgsmaptoolfillring.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,11 @@ void QgsMapToolFillRing::cadCanvasReleaseEvent( QgsMapMouseEvent *e )
164164
}
165165
else
166166
{
167-
QgsAttributeDialog *dialog = new QgsAttributeDialog( vlayer, &ft, false, nullptr, true );
167+
QgsAttributeEditorContext context;
168+
// don't set cadDockwidget in context because we don't want to be able to create geometries from this dialog
169+
// there is one modified and one created feature, so it's a mess of we start to digitize a relation feature geometry
170+
context.setVectorLayerTools( QgisApp::instance()->vectorLayerTools() );
171+
QgsAttributeDialog *dialog = new QgsAttributeDialog( vlayer, &ft, false, nullptr, true, context );
168172
dialog->setMode( QgsAttributeEditorContext::AddFeatureMode );
169173
res = dialog->exec(); // will also add the feature
170174
}

‎src/gui/editorwidgets/qgsrelationreferencewidget.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,7 @@ QgsRelationReferenceWidget::QgsRelationReferenceWidget( QWidget *parent )
156156
mHighlightFeatureButton->hide();
157157
mAttributeEditorFrame->hide();
158158
mInvalidLabel->hide();
159+
mAddEntryButton->hide();
159160

160161
// connect buttons
161162
connect( mOpenFormButton, &QAbstractButton::clicked, this, &QgsRelationReferenceWidget::openForm );
@@ -462,8 +463,12 @@ void QgsRelationReferenceWidget::setEditorContext( const QgsAttributeEditorConte
462463
mMapToolIdentify.reset( new QgsMapToolIdentifyFeature( mCanvas ) );
463464
mMapToolIdentify->setButton( mMapIdentificationButton );
464465

465-
mMapToolDigitize.reset( new QgsMapToolDigitizeFeature( mCanvas, context.cadDockWidget() ) );
466-
mMapToolDigitize->setButton( mAddEntryButton );
466+
if ( mEditorContext.cadDockWidget() )
467+
{
468+
mMapToolDigitize.reset( new QgsMapToolDigitizeFeature( mCanvas, mEditorContext.cadDockWidget() ) );
469+
mMapToolDigitize->setButton( mAddEntryButton );
470+
updateAddEntryButton();
471+
}
467472
}
468473

469474
void QgsRelationReferenceWidget::setEmbedForm( bool display )
@@ -1041,7 +1046,7 @@ void QgsRelationReferenceWidget::entryAdded( const QgsFeature &feat )
10411046

10421047
void QgsRelationReferenceWidget::updateAddEntryButton()
10431048
{
1044-
mAddEntryButton->setVisible( mAllowAddFeatures );
1049+
mAddEntryButton->setVisible( mAllowAddFeatures && mMapToolDigitize );
10451050
mAddEntryButton->setEnabled( mReferencedLayer && mReferencedLayer->isEditable() );
10461051
}
10471052

‎src/gui/editorwidgets/qgsrelationreferencewidget.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,11 @@ class GUI_EXPORT QgsRelationReferenceWidget : public QWidget
112112
*/
113113
QVariantList foreignKeys() const;
114114

115+
/**
116+
* Sets the editor \a context
117+
* \note if context cadDockWidget is null, it won't be possible to digitize
118+
* the geometry of a referenced feature from this widget
119+
*/
115120
void setEditorContext( const QgsAttributeEditorContext &context, QgsMapCanvas *canvas, QgsMessageBar *messageBar );
116121

117122
//! determines if the form of the related feature will be shown

‎src/gui/editorwidgets/qgsrelationreferencewidgetwrapper.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ void QgsRelationReferenceWidgetWrapper::initWidget( QWidget *editor )
8888
mWidget->setReadOnlySelector( true );
8989
mWidget->setAllowMapIdentification( false );
9090
mWidget->setOpenFormButtonVisible( false );
91+
mWidget->setAllowAddFeatures( false );
9192
break;
9293
}
9394
ctx = ctx->parentContext();

‎src/gui/qgsrelationeditorwidget.cpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,7 @@ void QgsRelationEditorWidget::initDualView( QgsVectorLayer *layer, const QgsFeat
282282
text = tr( "Add Polygon Feature" );
283283
}
284284

285-
if ( text.isEmpty() )
285+
if ( text.isEmpty() || !mEditorContext.mapCanvas() || !mEditorContext.cadDockWidget() )
286286
{
287287
mAddFeatureGeometryButton->setVisible( false );
288288
}
@@ -365,8 +365,12 @@ void QgsRelationEditorWidget::setRelations( const QgsRelation &relation, const Q
365365
void QgsRelationEditorWidget::setEditorContext( const QgsAttributeEditorContext &context )
366366
{
367367
mEditorContext = context;
368-
mMapToolDigitize.reset( new QgsMapToolDigitizeFeature( context.mapCanvas(), context.cadDockWidget() ) );
369-
mMapToolDigitize->setButton( mAddFeatureGeometryButton );
368+
369+
if ( context.mapCanvas() && context.cadDockWidget() )
370+
{
371+
mMapToolDigitize.reset( new QgsMapToolDigitizeFeature( context.mapCanvas(), context.cadDockWidget() ) );
372+
mMapToolDigitize->setButton( mAddFeatureGeometryButton );
373+
}
370374
}
371375

372376
QgsIFeatureSelectionManager *QgsRelationEditorWidget::featureSelectionManager()
@@ -442,6 +446,9 @@ void QgsRelationEditorWidget::addFeatureGeometry()
442446
layer = mRelation.referencingLayer();
443447

444448
mMapToolDigitize->setLayer( layer );
449+
450+
// window is always on top, so we hide it to digitize without seeing it
451+
window()->setVisible( false );
445452
setMapTool( mMapToolDigitize );
446453

447454
connect( mMapToolDigitize, &QgsMapToolDigitizeFeature::digitizingCompleted, this, &QgsRelationEditorWidget::onDigitizingCompleted );
@@ -958,6 +965,7 @@ void QgsRelationEditorWidget::onKeyPressed( QKeyEvent *e )
958965

959966
void QgsRelationEditorWidget::mapToolDeactivated()
960967
{
968+
window()->setVisible( true );
961969
window()->raise();
962970
window()->activateWindow();
963971

‎src/gui/qgsrelationeditorwidget.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,11 @@ class GUI_EXPORT QgsRelationEditorWidget : public QgsCollapsibleGroupBox
126126

127127
void setFeature( const QgsFeature &feature );
128128

129+
/**
130+
* Sets the editor \a context
131+
* \note if context cadDockWidget is null, it won't be possible to digitize
132+
* the geometry of a referencing feature from this widget
133+
*/
129134
void setEditorContext( const QgsAttributeEditorContext &context );
130135

131136
/**

0 commit comments

Comments
 (0)
Please sign in to comment.