Skip to content

Commit

Permalink
Fixes crash when displaying relation editor
Browse files Browse the repository at this point in the history
  • Loading branch information
Julien Cabieces authored and Hugo Mercier committed Mar 17, 2020
1 parent 9dc1ade commit 1c9e032
Show file tree
Hide file tree
Showing 14 changed files with 69 additions and 26 deletions.
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -77,6 +77,14 @@ Returns the related feature foreign keys
%End %End


void setEditorContext( const QgsAttributeEditorContext &context, QgsMapCanvas *canvas, QgsMessageBar *messageBar ); void setEditorContext( const QgsAttributeEditorContext &context, QgsMapCanvas *canvas, QgsMessageBar *messageBar );
%Docstring
Sets the editor ``context``

.. note::

if context cadDockWidget is null, it won't be possible to digitize
the geometry of a referenced feature from this widget
%End


bool embedForm(); bool embedForm();
%Docstring %Docstring
Expand Down
5 changes: 5 additions & 0 deletions python/gui/auto_generated/qgsrelationeditorwidget.sip.in
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -74,6 +74,11 @@ Sets the ``feature`` being edited and updates the UI unless ``update`` is set to
void setEditorContext( const QgsAttributeEditorContext &context ); void setEditorContext( const QgsAttributeEditorContext &context );
%Docstring %Docstring
Sets the editor ``context`` Sets the editor ``context``

.. note::

if context cadDockWidget is null, it won't be possible to digitize
the geometry of a referencing feature from this widget
%End %End


QgsIFeatureSelectionManager *featureSelectionManager(); QgsIFeatureSelectionManager *featureSelectionManager();
Expand Down
12 changes: 11 additions & 1 deletion src/app/qgisapp.cpp
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -9286,7 +9286,7 @@ void QgisApp::modifyAttributesOfSelectedFeatures()


//dummy feature //dummy feature
QgsFeature f; QgsFeature f;
QgsAttributeEditorContext context; QgsAttributeEditorContext context( createAttributeEditorContext() );
context.setAllowCustomUi( false ); context.setAllowCustomUi( false );
context.setVectorLayerTools( mVectorLayerTools ); context.setVectorLayerTools( mVectorLayerTools );
context.setCadDockWidget( mAdvancedDigitizingDockWidget ); context.setCadDockWidget( mAdvancedDigitizingDockWidget );
Expand Down Expand Up @@ -15572,3 +15572,13 @@ void QgisApp::triggerCrashHandler()
RaiseException( 0x12345678, 0, 0, nullptr ); RaiseException( 0x12345678, 0, 0, nullptr );
#endif #endif
} }

QgsAttributeEditorContext QgisApp::createAttributeEditorContext()
{
QgsAttributeEditorContext context;
context.setVectorLayerTools( vectorLayerTools() );
context.setMapCanvas( mapCanvas() );
context.setCadDockWidget( cadDockWidget() );
context.setMainMessageBar( messageBar() );
return context;
}
6 changes: 6 additions & 0 deletions src/app/qgisapp.h
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -1109,6 +1109,12 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow
//! Create a new spatial bookmark //! Create a new spatial bookmark
void newBookmark( bool inProject = false ); void newBookmark( bool inProject = false );


/**
* Creates a default attribute editor context using the main map canvas and the main edit tools and message bar
* \since QGIS 3.12
*/
QgsAttributeEditorContext createAttributeEditorContext();

protected: protected:


//! Handle state changes (WindowTitleChange) //! Handle state changes (WindowTitleChange)
Expand Down
6 changes: 1 addition & 5 deletions src/app/qgisappinterface.cpp
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -755,12 +755,8 @@ QgsAttributeDialog *QgisAppInterface::getFeatureForm( QgsVectorLayer *l, QgsFeat
myDa.setSourceCrs( l->crs(), QgsProject::instance()->transformContext() ); myDa.setSourceCrs( l->crs(), QgsProject::instance()->transformContext() );
myDa.setEllipsoid( QgsProject::instance()->ellipsoid() ); myDa.setEllipsoid( QgsProject::instance()->ellipsoid() );


QgsAttributeEditorContext context; QgsAttributeEditorContext context( QgisApp::instance()->createAttributeEditorContext() );
context.setDistanceArea( myDa ); context.setDistanceArea( myDa );
context.setVectorLayerTools( qgis->vectorLayerTools() );
context.setMapCanvas( qgis->mapCanvas() );
context.setCadDockWidget( qgis->cadDockWidget() );
context.setMainMessageBar( qgis->messageBar() );
QgsAttributeDialog *dialog = new QgsAttributeDialog( l, &feature, false, qgis, true, context ); QgsAttributeDialog *dialog = new QgsAttributeDialog( l, &feature, false, qgis, true, context );
if ( !feature.isValid() ) if ( !feature.isValid() )
{ {
Expand Down
11 changes: 4 additions & 7 deletions src/app/qgsattributetabledialog.cpp
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -152,12 +152,9 @@ QgsAttributeTableDialog::QgsAttributeTableDialog( QgsVectorLayer *layer, QgsAttr
QgsDistanceArea da; QgsDistanceArea da;
da.setSourceCrs( mLayer->crs(), QgsProject::instance()->transformContext() ); da.setSourceCrs( mLayer->crs(), QgsProject::instance()->transformContext() );
da.setEllipsoid( QgsProject::instance()->ellipsoid() ); da.setEllipsoid( QgsProject::instance()->ellipsoid() );
mEditorContext.setDistanceArea( da );


mEditorContext.setVectorLayerTools( QgisApp::instance()->vectorLayerTools() ); QgsAttributeEditorContext editorContext = QgisApp::instance()->createAttributeEditorContext();
mEditorContext.setMapCanvas( QgisApp::instance()->mapCanvas() ); editorContext.setDistanceArea( da );
mEditorContext.setMainMessageBar( QgisApp::instance()->messageBar() );
mEditorContext.setCadDockWidget( QgisApp::instance()->cadDockWidget() );


QgsFeatureRequest r; QgsFeatureRequest r;
bool needsGeom = false; bool needsGeom = false;
Expand All @@ -177,12 +174,12 @@ QgsAttributeTableDialog::QgsAttributeTableDialog( QgsVectorLayer *layer, QgsAttr
r.setFlags( QgsFeatureRequest::NoGeometry ); r.setFlags( QgsFeatureRequest::NoGeometry );


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


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


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


mActionFeatureActions = new QToolButton(); mActionFeatureActions = new QToolButton();
mActionFeatureActions->setAutoRaise( false ); mActionFeatureActions->setAutoRaise( false );
Expand Down
1 change: 0 additions & 1 deletion src/app/qgsattributetabledialog.h
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -221,7 +221,6 @@ class APP_EXPORT QgsAttributeTableDialog : public QDialog, private Ui::QgsAttrib


QPointer< QgsVectorLayer > mLayer = nullptr; QPointer< QgsVectorLayer > mLayer = nullptr;
QStringList mVisibleFields; QStringList mVisibleFields;
QgsAttributeEditorContext mEditorContext;


void updateMultiEditButtonState(); void updateMultiEditButtonState();
void deleteFeature( QgsFeatureId fid ); void deleteFeature( QgsFeatureId fid );
Expand Down
7 changes: 2 additions & 5 deletions src/app/qgsfeatureaction.cpp
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -53,22 +53,19 @@ QgsAttributeDialog *QgsFeatureAction::newDialog( bool cloneFeature )
{ {
QgsFeature *f = cloneFeature ? new QgsFeature( *mFeature ) : mFeature; QgsFeature *f = cloneFeature ? new QgsFeature( *mFeature ) : mFeature;


QgsAttributeEditorContext context; QgsAttributeEditorContext context( QgisApp::instance()->createAttributeEditorContext() );


QgsDistanceArea myDa; QgsDistanceArea myDa;


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


context.setDistanceArea( myDa ); context.setDistanceArea( myDa );
context.setVectorLayerTools( QgisApp::instance()->vectorLayerTools() );
context.setMapCanvas( QgisApp::instance()->mapCanvas() );
context.setCadDockWidget( QgisApp::instance()->cadDockWidget() );
context.setMainMessageBar( QgisApp::instance()->messageBar() );
context.setFormMode( QgsAttributeEditorContext::StandaloneDialog ); context.setFormMode( QgsAttributeEditorContext::StandaloneDialog );


QgsAttributeDialog *dialog = new QgsAttributeDialog( mLayer, f, cloneFeature, parentWidget(), true, context ); QgsAttributeDialog *dialog = new QgsAttributeDialog( mLayer, f, cloneFeature, parentWidget(), true, context );
dialog->setWindowFlags( dialog->windowFlags() | Qt::Tool ); dialog->setWindowFlags( dialog->windowFlags() | Qt::Tool );

dialog->setObjectName( QStringLiteral( "featureactiondlg:%1:%2" ).arg( mLayer->id() ).arg( f->id() ) ); dialog->setObjectName( QStringLiteral( "featureactiondlg:%1:%2" ).arg( mLayer->id() ).arg( f->id() ) );


QList<QgsAction> actions = mLayer->actions()->actions( QStringLiteral( "Feature" ) ); QList<QgsAction> actions = mLayer->actions()->actions( QStringLiteral( "Feature" ) );
Expand Down
6 changes: 5 additions & 1 deletion src/app/qgsmaptoolfillring.cpp
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -164,7 +164,11 @@ void QgsMapToolFillRing::cadCanvasReleaseEvent( QgsMapMouseEvent *e )
} }
else else
{ {
QgsAttributeDialog *dialog = new QgsAttributeDialog( vlayer, &ft, false, nullptr, true ); QgsAttributeEditorContext context;
// don't set cadDockwidget in context because we don't want to be able to create geometries from this dialog
// there is one modified and one created feature, so it's a mess of we start to digitize a relation feature geometry
context.setVectorLayerTools( QgisApp::instance()->vectorLayerTools() );
QgsAttributeDialog *dialog = new QgsAttributeDialog( vlayer, &ft, false, nullptr, true, context );
dialog->setMode( QgsAttributeEditorContext::AddFeatureMode ); dialog->setMode( QgsAttributeEditorContext::AddFeatureMode );
res = dialog->exec(); // will also add the feature res = dialog->exec(); // will also add the feature
} }
Expand Down
11 changes: 8 additions & 3 deletions src/gui/editorwidgets/qgsrelationreferencewidget.cpp
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ QgsRelationReferenceWidget::QgsRelationReferenceWidget( QWidget *parent )
mHighlightFeatureButton->hide(); mHighlightFeatureButton->hide();
mAttributeEditorFrame->hide(); mAttributeEditorFrame->hide();
mInvalidLabel->hide(); mInvalidLabel->hide();
mAddEntryButton->hide();


// connect buttons // connect buttons
connect( mOpenFormButton, &QAbstractButton::clicked, this, &QgsRelationReferenceWidget::openForm ); connect( mOpenFormButton, &QAbstractButton::clicked, this, &QgsRelationReferenceWidget::openForm );
Expand Down Expand Up @@ -429,8 +430,12 @@ void QgsRelationReferenceWidget::setEditorContext( const QgsAttributeEditorConte
mMapToolIdentify.reset( new QgsMapToolIdentifyFeature( mCanvas ) ); mMapToolIdentify.reset( new QgsMapToolIdentifyFeature( mCanvas ) );
mMapToolIdentify->setButton( mMapIdentificationButton ); mMapToolIdentify->setButton( mMapIdentificationButton );


mMapToolDigitize.reset( new QgsMapToolDigitizeFeature( mCanvas, context.cadDockWidget() ) ); if ( mEditorContext.cadDockWidget() )
mMapToolDigitize->setButton( mAddEntryButton ); {
mMapToolDigitize.reset( new QgsMapToolDigitizeFeature( mCanvas, mEditorContext.cadDockWidget() ) );
mMapToolDigitize->setButton( mAddEntryButton );
updateAddEntryButton();
}
} }


void QgsRelationReferenceWidget::setEmbedForm( bool display ) void QgsRelationReferenceWidget::setEmbedForm( bool display )
Expand Down Expand Up @@ -1006,7 +1011,7 @@ void QgsRelationReferenceWidget::entryAdded( const QgsFeature &feat )


void QgsRelationReferenceWidget::updateAddEntryButton() void QgsRelationReferenceWidget::updateAddEntryButton()
{ {
mAddEntryButton->setVisible( mAllowAddFeatures ); mAddEntryButton->setVisible( mAllowAddFeatures && mMapToolDigitize );
mAddEntryButton->setEnabled( mReferencedLayer && mReferencedLayer->isEditable() ); mAddEntryButton->setEnabled( mReferencedLayer && mReferencedLayer->isEditable() );
} }


Expand Down
5 changes: 5 additions & 0 deletions src/gui/editorwidgets/qgsrelationreferencewidget.h
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -112,6 +112,11 @@ class GUI_EXPORT QgsRelationReferenceWidget : public QWidget
*/ */
QVariantList foreignKeys() const; QVariantList foreignKeys() const;


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


//! determines if the form of the related feature will be shown //! determines if the form of the related feature will be shown
Expand Down
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ void QgsRelationReferenceWidgetWrapper::initWidget( QWidget *editor )
mWidget->setReadOnlySelector( true ); mWidget->setReadOnlySelector( true );
mWidget->setAllowMapIdentification( false ); mWidget->setAllowMapIdentification( false );
mWidget->setOpenFormButtonVisible( false ); mWidget->setOpenFormButtonVisible( false );
mWidget->setAllowAddFeatures( false );
break; break;
} }
ctx = ctx->parentContext(); ctx = ctx->parentContext();
Expand Down
14 changes: 11 additions & 3 deletions src/gui/qgsrelationeditorwidget.cpp
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -285,7 +285,7 @@ void QgsRelationEditorWidget::initDualView( QgsVectorLayer *layer, const QgsFeat
text = tr( "Add Polygon Feature" ); text = tr( "Add Polygon Feature" );
} }


if ( text.isEmpty() ) if ( text.isEmpty() || !mEditorContext.mapCanvas() || !mEditorContext.cadDockWidget() )
{ {
mAddFeatureGeometryButton->setVisible( false ); mAddFeatureGeometryButton->setVisible( false );
} }
Expand Down Expand Up @@ -368,8 +368,12 @@ void QgsRelationEditorWidget::setRelations( const QgsRelation &relation, const Q
void QgsRelationEditorWidget::setEditorContext( const QgsAttributeEditorContext &context ) void QgsRelationEditorWidget::setEditorContext( const QgsAttributeEditorContext &context )
{ {
mEditorContext = context; mEditorContext = context;
mMapToolDigitize.reset( new QgsMapToolDigitizeFeature( context.mapCanvas(), context.cadDockWidget() ) );
mMapToolDigitize->setButton( mAddFeatureGeometryButton ); if ( context.mapCanvas() && context.cadDockWidget() )
{
mMapToolDigitize.reset( new QgsMapToolDigitizeFeature( context.mapCanvas(), context.cadDockWidget() ) );
mMapToolDigitize->setButton( mAddFeatureGeometryButton );
}
} }


QgsIFeatureSelectionManager *QgsRelationEditorWidget::featureSelectionManager() QgsIFeatureSelectionManager *QgsRelationEditorWidget::featureSelectionManager()
Expand Down Expand Up @@ -448,6 +452,9 @@ void QgsRelationEditorWidget::addFeatureGeometry()
layer = mRelation.referencingLayer(); layer = mRelation.referencingLayer();


mMapToolDigitize->setLayer( layer ); mMapToolDigitize->setLayer( layer );

// window is always on top, so we hide it to digitize without seeing it
window()->setVisible( false );
setMapTool( mMapToolDigitize ); setMapTool( mMapToolDigitize );


connect( mMapToolDigitize, &QgsMapToolDigitizeFeature::digitizingCompleted, this, &QgsRelationEditorWidget::onDigitizingCompleted ); connect( mMapToolDigitize, &QgsMapToolDigitizeFeature::digitizingCompleted, this, &QgsRelationEditorWidget::onDigitizingCompleted );
Expand Down Expand Up @@ -984,6 +991,7 @@ void QgsRelationEditorWidget::onKeyPressed( QKeyEvent *e )


void QgsRelationEditorWidget::mapToolDeactivated() void QgsRelationEditorWidget::mapToolDeactivated()
{ {
window()->setVisible( true );
window()->raise(); window()->raise();
window()->activateWindow(); window()->activateWindow();


Expand Down
2 changes: 2 additions & 0 deletions src/gui/qgsrelationeditorwidget.h
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -134,6 +134,8 @@ class GUI_EXPORT QgsRelationEditorWidget : public QgsCollapsibleGroupBox


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


Expand Down

0 comments on commit 1c9e032

Please sign in to comment.