Skip to content

Commit

Permalink
fix #2879 photo crash on project switch
Browse files Browse the repository at this point in the history
  • Loading branch information
PeterPetrik committed Oct 27, 2023
1 parent a1ff0c4 commit 40ca5a1
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 38 deletions.
73 changes: 38 additions & 35 deletions app/attributes/attributecontroller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -359,59 +359,59 @@ void AttributeController::clearAll()
void AttributeController::updateOnLayerChange()
{
clearAll();
QgsVectorLayer *layer = mFeatureLayerPair.layer();
if ( !layer )
return;

// 1) DATA
QgsVectorLayer *layer = mFeatureLayerPair.layer();
if ( layer )
if ( layer->editFormConfig().layout() == Qgis::AttributeFormLayout::DragAndDrop )
{
if ( layer->editFormConfig().layout() == Qgis::AttributeFormLayout::DragAndDrop )
QgsAttributeEditorContainer *root = layer->editFormConfig().invisibleRootContainer();
if ( root->columnCount() > 1 )
{
QgsAttributeEditorContainer *root = layer->editFormConfig().invisibleRootContainer();
if ( root->columnCount() > 1 )
{
qDebug() << "root tab in manual config has multiple columns. not supported on mobile devices!";
root->setColumnCount( 1 );
}
qDebug() << "root tab in manual config has multiple columns. not supported on mobile devices!";
root->setColumnCount( 1 );
}

mHasTabs = allowTabs( root );
if ( mHasTabs )
mHasTabs = allowTabs( root );
if ( mHasTabs )
{
for ( QgsAttributeEditorElement *element : root->children() )
{
for ( QgsAttributeEditorElement *element : root->children() )
if ( element->type() == Qgis::AttributeEditorType::Container )
{
if ( element->type() == Qgis::AttributeEditorType::Container )
QgsAttributeEditorContainer *container = static_cast<QgsAttributeEditorContainer *>( element );
if ( container->columnCount() > 1 )
{
QgsAttributeEditorContainer *container = static_cast<QgsAttributeEditorContainer *>( element );
if ( container->columnCount() > 1 )
{
qDebug() << "tab " << container->name() << " in manual config has multiple columns. not supported on mobile devices!";
container->setColumnCount( 1 );
}
createTab( container );
qDebug() << "tab " << container->name() << " in manual config has multiple columns. not supported on mobile devices!";
container->setColumnCount( 1 );
}
createTab( container );
}
}
else
{
createTab( root );
}
}
else
{
// Auto-Generated Layout
// We create fake root tab
QgsAttributeEditorContainer *tab = autoLayoutTabContainer();

// We need to look for relations and include them into form,
// in auto-generated layout they are not included in form config
discoverRelations( tab );

createTab( tab );
createTab( root );
}
}
else
{
// Auto-Generated Layout
// We create fake root tab
QgsAttributeEditorContainer *tab = autoLayoutTabContainer();

// We need to look for relations and include them into form,
// in auto-generated layout they are not included in form config
discoverRelations( tab );

if ( mRememberAttributesController )
mRememberAttributesController->storeLayerFields( layer );
createTab( tab );
}

if ( mRememberAttributesController )
mRememberAttributesController->storeLayerFields( layer );


// 2) MODELS
// for all other models, ownership is managed by Qt parent system
AttributeTabModel *tabModel = new AttributeTabModel( mAttributeTabProxyModel.get(), this, mTabItems.size() );
Expand Down Expand Up @@ -462,6 +462,9 @@ void AttributeController::updateOnLayerChange()

void AttributeController::updateOnFeatureChange()
{
if ( !mFeatureLayerPair.layer() )
return;

const QgsFeature feature = mFeatureLayerPair.feature();

QMap<QUuid, std::shared_ptr<FormItem>>::iterator formItemsIterator = mFormItems.begin();
Expand Down
2 changes: 1 addition & 1 deletion app/inpututils.h
Original file line number Diff line number Diff line change
Expand Up @@ -470,7 +470,7 @@ class InputUtils: public QObject
Q_INVOKABLE static QString featureTitle( const FeatureLayerPair &pair, QgsProject *project );

//! Creates featureLayerPair from geometry and layer, evaluates its expressions and returns it.
Q_INVOKABLE static FeatureLayerPair createFeatureLayerPair( QgsVectorLayer *layer, const QgsGeometry &geometry, VariablesManager *variablesmanager, QgsExpressionContextScope *additionalScope = nullptr );
Q_INVOKABLE static FeatureLayerPair createFeatureLayerPair( QgsVectorLayer *layer = nullptr, const QgsGeometry &geometry = QgsGeometry(), VariablesManager *variablesmanager = nullptr , QgsExpressionContextScope *additionalScope = nullptr );

Q_INVOKABLE static void createEditBuffer( QgsVectorLayer *layer );

Expand Down
25 changes: 24 additions & 1 deletion app/qml/FormsStackManager.qml
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,11 @@ Item {
}

function _getActiveForm() {
if (formsStack.depth === 0) {
// no active form on empty form stack
return null
}

if ( root.activeFormIndex >= 0 && root.activeFormIndex < formsStack.depth ) {
return formsStack.get( activeFormIndex )
}
Expand Down Expand Up @@ -137,7 +142,25 @@ Item {
}

function reload() {
formsStack.clear() // removes all objects thanks to Qt parent system
// Even after formStack.clear() is called,
// forms in the formStack will still
// receive and evaluate some signals
// and most importantly in some scenarios
// featureLayerPair could contain already
// dangling pointer to layer and crash the app
// https://github.com/MerginMaps/input/issues/2879
for ( let i = 0; i < formsStack.depth; i++ ) {
let form = formsStack.get( i )
form.featureLayerPair = __inputUtils.createFeatureLayerPair()
form.relationToApply = null
form.controllerToApply = null
form.project = null
form.linkedRelation = null
form.parentController = null
}

// removes all objects thanks to Qt parent system
formsStack.clear(StackView.Immediate)
}

function openLinkedFeature( linkedFeature ) {
Expand Down
2 changes: 1 addition & 1 deletion app/qml/form/FormWrapper.qml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ Item {
property real previewHeight
property real panelHeight

property bool isReadOnly: featureLayerPair ? featureLayerPair.layer.readOnly : false
property bool isReadOnly: featureLayerPair && featureLayerPair.layer ? featureLayerPair.layer.readOnly : false

signal closed()
signal editGeometry( var pair )
Expand Down

0 comments on commit 40ca5a1

Please sign in to comment.