Do dialogs not open modal since otherwise the canvas are blocked and we are not able to collect geometries.

Pass widget as parent to the dialog to avoid "orphaned" child dialogs. The widget is passed as parent to QgsFeatureAction. When creating a dialog the widget is passed as parent to the dialog and the dialog is set as parent to the QgsFeatureAction (last like before).
To avoid confusion with opened dialogs the parent's visibility is set to hidden, when child dialog is opened.

This fixes #47193
This commit is contained in:
signedav 2022-02-14 17:56:36 +01:00
parent ef85926a5d
commit f971a47b67
13 changed files with 53 additions and 24 deletions

View File

@ -20,7 +20,7 @@ class QgsTrackedVectorLayerTools : QgsVectorLayerTools
Constructor for QgsTrackedVectorLayerTools.
%End
virtual bool addFeature( QgsVectorLayer *layer, const QgsAttributeMap &defaultValues, const QgsGeometry &defaultGeometry, QgsFeature *feature ) const;
virtual bool addFeature( QgsVectorLayer *layer, const QgsAttributeMap &defaultValues, const QgsGeometry &defaultGeometry, QgsFeature *feature, QWidget *parentWidget = 0, bool showModal = true, bool hideParent = false ) const;
virtual bool startEditing( QgsVectorLayer *layer ) const;

View File

@ -28,7 +28,7 @@ in your application.
QgsVectorLayerTools();
virtual bool addFeature( QgsVectorLayer *layer, const QgsAttributeMap &defaultValues = QgsAttributeMap(), const QgsGeometry &defaultGeometry = QgsGeometry(), QgsFeature *feature /Out/ = 0 ) const = 0;
virtual bool addFeature( QgsVectorLayer *layer, const QgsAttributeMap &defaultValues = QgsAttributeMap(), const QgsGeometry &defaultGeometry = QgsGeometry(), QgsFeature *feature /Out/ = 0, QWidget *parentWidget = 0, bool showModal = true, bool hideParent = false ) const = 0;
%Docstring
This method should/will be called, whenever a new feature will be added to the layer

View File

@ -99,7 +99,6 @@ QgsAttributeDialog *QgsFeatureAction::newDialog( bool cloneFeature )
connect( pb, &QAbstractButton::clicked, a, &QgsFeatureAction::execute );
}
}
return dialog;
}
@ -168,7 +167,7 @@ bool QgsFeatureAction::editFeature( bool showModal )
return true;
}
bool QgsFeatureAction::addFeature( const QgsAttributeMap &defaultAttributes, bool showModal, QgsExpressionContextScope *scope SIP_TRANSFER )
bool QgsFeatureAction::addFeature( const QgsAttributeMap &defaultAttributes, bool showModal, QgsExpressionContextScope *scope SIP_TRANSFER, bool hideParent )
{
if ( !mLayer || !mLayer->isEditable() )
return false;
@ -254,7 +253,6 @@ bool QgsFeatureAction::addFeature( const QgsAttributeMap &defaultAttributes, boo
}
else
{
QgsAttributeDialog *dialog = newDialog( false );
// delete the dialog when it is closed
dialog->setAttribute( Qt::WA_DeleteOnClose );
@ -270,6 +268,12 @@ bool QgsFeatureAction::addFeature( const QgsAttributeMap &defaultAttributes, boo
setParent( dialog ); // keep dialog until the dialog is closed and destructed
connect( dialog, &QgsAttributeDialog::finished, this, &QgsFeatureAction::addFeatureFinished );
dialog->show();
if ( hideParent )
{
connect( this, &QgsFeatureAction::addFeatureFinished, this, &QgsFeatureAction::unhideParentWidget );
hideParentWidget();
}
mFeature = nullptr;
return true;
}
@ -314,6 +318,22 @@ void QgsFeatureAction::onFeatureSaved( const QgsFeature &feature )
}
}
void QgsFeatureAction::hideParentWidget()
{
if ( parentWidget() && parentWidget()->parentWidget() )
{
parentWidget()->parentWidget()->window()->setVisible( false );
}
}
void QgsFeatureAction::unhideParentWidget()
{
if ( parentWidget() && parentWidget()->parentWidget() )
{
parentWidget()->parentWidget()->window()->setVisible( true );
}
}
QgsFeature QgsFeatureAction::feature() const
{
return mFeature ? *mFeature : QgsFeature();

View File

@ -52,7 +52,7 @@ class APP_EXPORT QgsFeatureAction : public QAction
*
* \returns TRUE if feature was added if showModal is true. If showModal is FALSE, returns TRUE in every case
*/
bool addFeature( const QgsAttributeMap &defaultAttributes = QgsAttributeMap(), bool showModal = true, QgsExpressionContextScope *scope = nullptr );
bool addFeature( const QgsAttributeMap &defaultAttributes = QgsAttributeMap(), bool showModal = true, QgsExpressionContextScope *scope = nullptr, bool hideParent = false );
/**
* Sets whether to force suppression of the attribute form popup after creating a new feature.
@ -79,6 +79,8 @@ class APP_EXPORT QgsFeatureAction : public QAction
private slots:
void onFeatureSaved( const QgsFeature &feature );
void unhideParentWidget();
void hideParentWidget();
private:
QgsAttributeDialog *newDialog( bool cloneFeature );
@ -86,6 +88,7 @@ class APP_EXPORT QgsFeatureAction : public QAction
QgsVectorLayer *mLayer = nullptr;
QgsFeature *mFeature = nullptr;
QUuid mActionId;
QWidget *mParentWidget = nullptr;
int mIdx;
bool mFeatureSaved;

View File

@ -29,19 +29,20 @@
#include "qgsvectordataprovider.h"
#include "qgsvectorlayer.h"
bool QgsGuiVectorLayerTools::addFeature( QgsVectorLayer *layer, const QgsAttributeMap &defaultValues, const QgsGeometry &defaultGeometry, QgsFeature *feat ) const
bool QgsGuiVectorLayerTools::addFeature( QgsVectorLayer *layer, const QgsAttributeMap &defaultValues, const QgsGeometry &defaultGeometry, QgsFeature *feat, QWidget *parentWidget, bool showModal, bool hideParent ) const
{
QgsFeature *f = feat;
if ( !feat )
f = new QgsFeature();
f->setGeometry( defaultGeometry );
QgsFeatureAction a( tr( "Add feature" ), *f, layer );
a.setForceSuppressFormPopup( forceSuppressFormPopup() );
const bool added = a.addFeature( defaultValues );
QgsFeatureAction *a = new QgsFeatureAction( tr( "Add feature" ), *f, layer, QString(), -1, parentWidget );
a->setForceSuppressFormPopup( forceSuppressFormPopup() );
const bool added = a->addFeature( defaultValues, showModal, nullptr, hideParent );
if ( !feat )
delete f;
if ( showModal )
delete a;
return added;
}

View File

@ -43,7 +43,7 @@ class QgsGuiVectorLayerTools : public QgsVectorLayerTools
*
* \returns TRUE in case of success, FALSE if the operation failed/was aborted
*/
bool addFeature( QgsVectorLayer *layer, const QgsAttributeMap &defaultValues, const QgsGeometry &defaultGeometry, QgsFeature *feat = nullptr ) const override;
bool addFeature( QgsVectorLayer *layer, const QgsAttributeMap &defaultValues, const QgsGeometry &defaultGeometry, QgsFeature *feat = nullptr, QWidget *parentWidget = nullptr, bool showModal = true, bool hideParent = false ) const ;
/**
* This should be called, whenever a vector layer should be switched to edit mode. If successful

View File

@ -17,7 +17,7 @@
#include "qgsvectorlayer.h"
bool QgsTrackedVectorLayerTools::addFeature( QgsVectorLayer *layer, const QgsAttributeMap &defaultValues, const QgsGeometry &defaultGeometry, QgsFeature *feature ) const
bool QgsTrackedVectorLayerTools::addFeature( QgsVectorLayer *layer, const QgsAttributeMap &defaultValues, const QgsGeometry &defaultGeometry, QgsFeature *feature, QWidget *parentWidget, bool showModal, bool hideParent ) const
{
QgsFeature *f = feature;
if ( !feature )
@ -25,7 +25,7 @@ bool QgsTrackedVectorLayerTools::addFeature( QgsVectorLayer *layer, const QgsAtt
const_cast<QgsVectorLayerTools *>( mBackend )->setForceSuppressFormPopup( forceSuppressFormPopup() );
if ( mBackend->addFeature( layer, defaultValues, defaultGeometry, f ) )
if ( mBackend->addFeature( layer, defaultValues, defaultGeometry, f, parentWidget, showModal, hideParent ) )
{
mAddedFeatures[layer].insert( f->id() );
if ( !feature )

View File

@ -33,7 +33,7 @@ class CORE_EXPORT QgsTrackedVectorLayerTools : public QgsVectorLayerTools
*/
QgsTrackedVectorLayerTools() = default;
bool addFeature( QgsVectorLayer *layer, const QgsAttributeMap &defaultValues, const QgsGeometry &defaultGeometry, QgsFeature *feature ) const override;
bool addFeature( QgsVectorLayer *layer, const QgsAttributeMap &defaultValues, const QgsGeometry &defaultGeometry, QgsFeature *feature, QWidget *parentWidget = nullptr, bool showModal = true, bool hideParent = false ) const override;
bool startEditing( QgsVectorLayer *layer ) const override;
bool stopEditing( QgsVectorLayer *layer, bool allowCancel ) const override;
bool saveEdits( QgsVectorLayer *layer ) const override;

View File

@ -55,7 +55,7 @@ class CORE_EXPORT QgsVectorLayerTools : public QObject
* \returns TRUE in case of success, FALSE if the operation failed/was aborted
*
*/
virtual bool addFeature( QgsVectorLayer *layer, const QgsAttributeMap &defaultValues = QgsAttributeMap(), const QgsGeometry &defaultGeometry = QgsGeometry(), QgsFeature *feature SIP_OUT = nullptr ) const = 0;
virtual bool addFeature( QgsVectorLayer *layer, const QgsAttributeMap &defaultValues = QgsAttributeMap(), const QgsGeometry &defaultGeometry = QgsGeometry(), QgsFeature *feature SIP_OUT = nullptr, QWidget *parentWidget = nullptr, bool showModal = true, bool hideParent = false ) const = 0;
// TODO QGIS 4: remove const qualifier

View File

@ -908,7 +908,7 @@ void QgsRelationReferenceWidget::entryAdded( const QgsFeature &feat )
}
}
if ( mEditorContext.vectorLayerTools()->addFeature( mReferencedLayer, attributes, f.geometry(), &f ) )
if ( mEditorContext.vectorLayerTools()->addFeature( mReferencedLayer, attributes, f.geometry(), &f, this, false, true ) )
{
QVariantList attrs;
for ( const QString &fieldName : std::as_const( mReferencedFields ) )

View File

@ -241,7 +241,7 @@ QgsFeatureIds QgsAbstractRelationEditorWidget::addFeature( const QgsGeometry &ge
// n:m Relation: first let the user create a new feature on the other table
// and autocreate a new linking feature.
QgsFeature finalFeature;
if ( !vlTools->addFeature( mNmRelation.referencedLayer(), QgsAttributeMap(), geometry, &finalFeature ) )
if ( !vlTools->addFeature( mNmRelation.referencedLayer(), QgsAttributeMap(), geometry, &finalFeature, this, false, true ) )
return QgsFeatureIds();
addedFeatureIds.insert( finalFeature.id() );
@ -280,7 +280,7 @@ QgsFeatureIds QgsAbstractRelationEditorWidget::addFeature( const QgsGeometry &ge
keyAttrs.insert( fields.indexFromName( fieldPair.referencingField() ), mFeatureList.first().attribute( fieldPair.referencedField() ) );
QgsFeature linkFeature;
if ( !vlTools->addFeature( mRelation.referencingLayer(), keyAttrs, geometry, &linkFeature ) )
if ( !vlTools->addFeature( mRelation.referencingLayer(), keyAttrs, geometry, &linkFeature, this, false, true ) )
return QgsFeatureIds();
addedFeatureIds.insert( linkFeature.id() );

View File

@ -450,6 +450,9 @@ void QgsRelationEditorWidget::addFeatureGeometry()
void QgsRelationEditorWidget::onDigitizingCompleted( const QgsFeature &feature )
{
window()->setVisible( true );
window()->raise();
window()->activateWindow();
QgsAbstractRelationEditorWidget::addFeature( feature.geometry() );
unsetMapTool();
@ -780,16 +783,15 @@ void QgsRelationEditorWidget::onKeyPressed( QKeyEvent *e )
{
if ( e->key() == Qt::Key_Escape )
{
window()->setVisible( true );
window()->raise();
window()->activateWindow();
unsetMapTool();
}
}
void QgsRelationEditorWidget::mapToolDeactivated()
{
window()->setVisible( true );
window()->raise();
window()->activateWindow();
if ( mEditorContext.mainMessageBar() && mMessageBarItem )
{
mEditorContext.mainMessageBar()->popWidget( mMessageBarItem );

View File

@ -582,8 +582,11 @@ void TestQgsRelationReferenceWidget::testIdentifyOnMap()
// referenced layer
class DummyVectorLayerTools : public QgsVectorLayerTools // clazy:exclude=missing-qobject-macro
{
bool addFeature( QgsVectorLayer *layer, const QgsAttributeMap &, const QgsGeometry &, QgsFeature *feat = nullptr ) const override
bool addFeature( QgsVectorLayer *layer, const QgsAttributeMap &, const QgsGeometry &, QgsFeature *feat = nullptr, QWidget *parentWidget = nullptr, bool showModal = true, bool hideParent = false ) const override
{
Q_UNUSED( parentWidget );
Q_UNUSED( showModal );
Q_UNUSED( hideParent );
feat->setAttribute( QStringLiteral( "pk" ), 13 );
feat->setAttribute( QStringLiteral( "material" ), QStringLiteral( "steel" ) );
feat->setAttribute( QStringLiteral( "diameter" ), 140 );