Bugfix/fix reuse last entered value - #4668
Conversation
📦 Build Artifacts Ready
|
Coverage Report for CI Build 32851633524Warning No base build found for commit Coverage: 59.064%Details
Uncovered ChangesNo uncovered changes found. Coverage RegressionsRequires a base build to compare against. How to fix this → Coverage Stats
💛 - Coveralls |
📦 Build Artifacts Ready
|
Withalion
left a comment
There was a problem hiding this comment.
Looks like in some cases the photo renaming doesn't work correctly. Either it get's renamed again, when using now() or the name somehow gets mixed with previous value as well. Have a look at this project Matej-test/photo-naming-expr and POI layer.
Renaming gets triggered on empty photo fields with reuse last entered value turned on.
My comment on the issue about unlinking/deleting is addressed by #4685?
Add some unit tests for using default value on photos in testattributecontroller.h
| mFormItems[itemData->id()]->setOriginalValue( newVal ); | ||
| mFormItems[itemData->id()]->setRawValue( newVal ); // we need to set raw value as well, as we use it in form now | ||
| if ( mRememberAttributesController && isNewFeature() ) // this is a new feature | ||
| itemData->setReusedValue( false ); |
There was a problem hiding this comment.
I would reuse the access approach above
| mFormItems[itemData->id()]->setRawValue( newVal ); // we need to set raw value as well, as we use it in form now | ||
| if ( mRememberAttributesController && isNewFeature() ) // this is a new feature | ||
| itemData->setReusedValue( false ); | ||
| if ( mRememberAttributesController && isNewFeature() && newVal.toString().isEmpty() ) |
There was a problem hiding this comment.
won't the new condition somehow mess up other fieldtypes? or was it just expected until now?
| ( isFirstUpdateOfNewFeature || ( isFormValueChange && defaultDefinition.applyOnUpdate() ) ) && | ||
| !item->isReusedValue(); |
There was a problem hiding this comment.
why is this necessary, what does it solve?
| if ( rv ) | ||
| { | ||
| discardReusedPhotoCopies( false ); | ||
| } |
There was a problem hiding this comment.
what's the case we want to remove photocopies on successful save?
| QString reusedCopyPath() const; | ||
| void setReusedCopyPath( const QString &path ); |
There was a problem hiding this comment.
can't we instead of this field reuse rawValue?
Description
Fixes a bug where enabling "Use last entered value" on a photo/file field causes the previous feature's photo file to be corrupted, renamed, or orphaned when reused by a new feature - most visibly when a custom filename expression is set in QGIS, where the previous feature's file gets physically renamed and reassigned to the new feature, leaving the previous feature with a broken/missing image.
Fixes: #4487
What changed
AttributeController::updateOnFeatureChange()now clones the underlying file when a photo/file field's value is reused, instead of just copying the path string. Each feature gets its own independent file from the moment the drawer opens, so it's never possible for two features to end up sharing (and therefore corrupting) the same photo.FormItem(isReusedValue(),reusedCopyPath()) so it can be cleaned up if it's never actually needed:AttributeController::discardReusedPhotoCopies()deletes it if the draft feature is discarded (cancel/rollback), or if the photo is deleted or replaced before the feature is saved.renamePhotos()now evaluates the project's custom filename expression fresh against the clone (instead of skipping reused fields entirely), so a reused photo gets a correctly computed, per-feature filename rather than a generic incremented name. A static expression that collides with an existing file still gets a proper incremental suffix.recalculateDefaultValues()no longer lets a QGIS field-level Default Value expression overwrite a value that was just populated by "reuse last entered value" while the form is open.InputUtils::resolveTargetDir()now resolves a relative root path expression/Default Path against the project home path. Previously a relative path (e.g.'photos/' + @layer_name) was used as-is, which could resolve to the wrong location on disk and produce a broken/missing image.MMActivity.importImage) and iOS (IOSGalleryPickerDelegate) gallery import now create the destination directory before copying the picked image, matching what capture-from-camera already did.Behaviour
TLDR @Withalion
"Use last entered value" on a photo field now clones the file per feature instead of sharing/renaming the original, so reused photos never corrupt or orphan another feature's image, on save or on cancel.