#1539 locked: review, prevent rename / metadata export

This commit is contained in:
Thibault Deckers 2025-04-27 23:42:40 +02:00
parent bb6c2c341b
commit a8bb2eb69f
8 changed files with 39 additions and 35 deletions

View file

@ -37,7 +37,7 @@ extension ExtraAvesEntryMetadataEdition on AvesEntry {
return {};
}
if (canEditExif && appliedModifier.fields.any((v) => v.type == MetadataType.exif)) {
if (isExifEditionSupported && appliedModifier.fields.any((v) => v.type == MetadataType.exif)) {
final newFields = await metadataEditService.editExifDate(this, appliedModifier);
if (newFields.isNotEmpty) {
dataTypes.addAll({
@ -47,7 +47,7 @@ extension ExtraAvesEntryMetadataEdition on AvesEntry {
}
}
if (canEditXmp && appliedModifier.fields.any((v) => v.type == MetadataType.xmp)) {
if (isXmpEditionSupported && appliedModifier.fields.any((v) => v.type == MetadataType.xmp)) {
final metadata = {
MetadataType.xmp: await _editXmp((descriptions) {
switch (appliedModifier.action) {
@ -94,7 +94,7 @@ extension ExtraAvesEntryMetadataEdition on AvesEntry {
final missingDate = await _missingDateCheckAndExifEdit(dataTypes);
if (canEditExif) {
if (isExifEditionSupported) {
// clear every GPS field
final exifFields = Map<MetadataField, dynamic>.fromEntries(MetadataFields.exifGpsFields.map((k) => MapEntry(k, null)));
// add latitude & longitude, if any
@ -110,7 +110,7 @@ extension ExtraAvesEntryMetadataEdition on AvesEntry {
}
metadata[MetadataType.exif] = Map<String, dynamic>.fromEntries(exifFields.entries.map((kv) => MapEntry(kv.key.toPlatform!, kv.value)));
if (canEditXmp && missingDate != null) {
if (isXmpEditionSupported && missingDate != null) {
metadata[MetadataType.xmp] = await _editXmp((descriptions) {
editCreateDateXmp(descriptions, missingDate);
return true;
@ -236,14 +236,14 @@ extension ExtraAvesEntryMetadataEdition on AvesEntry {
final title = fields[DescriptionField.title];
final description = fields[DescriptionField.description];
if (canEditExif && editDescription) {
if (isExifEditionSupported && editDescription) {
metadata[MetadataType.exif] = {
MetadataField.exifImageDescription.toPlatform!: null,
MetadataField.exifUserComment.toPlatform!: null,
};
}
if (canEditIptc) {
if (isIptcEditionSupported) {
final iptc = await metadataFetchService.getIptc(this);
if (iptc != null) {
if (editTitle) {
@ -256,7 +256,7 @@ extension ExtraAvesEntryMetadataEdition on AvesEntry {
}
}
if (canEditXmp) {
if (isXmpEditionSupported) {
metadata[MetadataType.xmp] = await _editXmp((descriptions) {
var modified = false;
if (editTitle) {
@ -304,7 +304,7 @@ extension ExtraAvesEntryMetadataEdition on AvesEntry {
final missingDate = await _missingDateCheckAndExifEdit(dataTypes);
if (canEditIptc) {
if (isIptcEditionSupported) {
final iptc = await metadataFetchService.getIptc(this);
if (iptc != null) {
editIptcValues(iptc, IPTC.applicationRecord, IPTC.keywordsTag, tags);
@ -312,7 +312,7 @@ extension ExtraAvesEntryMetadataEdition on AvesEntry {
}
}
if (canEditXmp) {
if (isXmpEditionSupported) {
metadata[MetadataType.xmp] = await _editXmp((descriptions) {
final modified = editTagsXmp(descriptions, tags);
if (modified && missingDate != null) {
@ -342,7 +342,7 @@ extension ExtraAvesEntryMetadataEdition on AvesEntry {
final missingDate = await _missingDateCheckAndExifEdit(dataTypes);
if (canEditXmp) {
if (isXmpEditionSupported) {
metadata[MetadataType.xmp] = await _editXmp((descriptions) {
final modified = editRatingXmp(descriptions, rating);
if (modified && missingDate != null) {
@ -368,7 +368,7 @@ extension ExtraAvesEntryMetadataEdition on AvesEntry {
final dataTypes = <EntryDataType>{};
final metadata = <MetadataType, dynamic>{};
if (!canEditXmp) return dataTypes;
if (!isXmpEditionSupported) return dataTypes;
final missingDate = await _missingDateCheckAndExifEdit(dataTypes);
@ -509,7 +509,7 @@ extension ExtraAvesEntryMetadataEdition on AvesEntry {
return null;
}
if (canEditExif) {
if (isExifEditionSupported) {
final newFields = await metadataEditService.editExifDate(this, DateModifier.setCustom(const {MetadataField.exifDateOriginal}, date));
if (newFields.isNotEmpty) {
dataTypes.addAll({
@ -524,7 +524,7 @@ extension ExtraAvesEntryMetadataEdition on AvesEntry {
}
Future<DateModifier?> _applyDateModifierToEntry(DateModifier modifier) async {
Set<MetadataField> mainMetadataDate() => {canEditExif ? MetadataField.exifDateOriginal : MetadataField.xmpXmpCreateDate};
Set<MetadataField> mainMetadataDate() => {isExifEditionSupported ? MetadataField.exifDateOriginal : MetadataField.xmpXmpCreateDate};
switch (modifier.action) {
case DateEditAction.copyField:

View file

@ -112,29 +112,29 @@ extension ExtraAvesEntryProps on AvesEntry {
bool get canEdit => !settings.isReadOnly && path != null && !trashed && (_isMediaStoreContent || _isVaultContent);
bool get canEditDate => canEdit && (canEditExif || canEditXmp);
bool get canEditDate => canEdit && (isExifEditionSupported || isXmpEditionSupported);
bool get canEditLocation => canEdit && (canEditExif || mimeType == MimeTypes.mp4);
bool get canEditLocation => canEdit && (isExifEditionSupported || mimeType == MimeTypes.mp4);
bool get canEditTitleDescription => canEdit && canEditXmp;
bool get canEditTitleDescription => canEdit && isXmpEditionSupported;
bool get canEditRating => canEdit && canEditXmp;
bool get canEditRating => canEdit && isXmpEditionSupported;
bool get canEditTags => canEdit && canEditXmp;
bool get canEditTags => canEdit && isXmpEditionSupported;
bool get canRotate => canEdit && (canEditExif || mimeType == MimeTypes.mp4);
bool get canRotate => canEdit && (isExifEditionSupported || mimeType == MimeTypes.mp4);
bool get canFlip => canEdit && canEditExif;
bool get canFlip => canEdit && isExifEditionSupported;
// app support
bool get canDecode => AppSupport.canDecode(mimeType);
bool get isDecodingSupported => AppSupport.canDecode(mimeType);
bool get canEditExif => AppSupport.canEditExif(mimeType);
bool get isExifEditionSupported => AppSupport.canEditExif(mimeType);
bool get canEditIptc => AppSupport.canEditIptc(mimeType);
bool get isIptcEditionSupported => AppSupport.canEditIptc(mimeType);
bool get canEditXmp => AppSupport.canEditXmp(mimeType);
bool get isXmpEditionSupported => AppSupport.canEditXmp(mimeType);
bool get canRemoveMetadata => AppSupport.canRemoveMetadata(mimeType);
bool get isMetadataRemovalSupported => AppSupport.canRemoveMetadata(mimeType);
}

View file

@ -670,7 +670,7 @@ class EntrySetActionDelegate with FeedbackMixin, PermissionAwareMixin, SizeAware
}
Future<void> _removeMetadata(BuildContext context) async {
final entries = await _getEditableTargetItems(context, canEdit: (entry) => entry.canRemoveMetadata);
final entries = await _getEditableTargetItems(context, canEdit: (entry) => entry.isMetadataRemovalSupported);
if (entries == null || entries.isEmpty) return;
final types = await selectMetadataToRemove(context, entries);

View file

@ -103,7 +103,7 @@ class _ThumbnailImageState extends State<ThumbnailImage> {
}
void _initProvider() {
if (!entry.canDecode) return;
if (!entry.isDecodingSupported) return;
_lastException = null;
_providers.clear();
@ -192,7 +192,7 @@ class _ThumbnailImageState extends State<ThumbnailImage> {
@override
Widget build(BuildContext context) {
final animate = context.select<Settings, bool>((v) => v.animate);
if (!entry.canDecode || _lastException != null) {
if (!entry.isDecodingSupported || _lastException != null) {
return _buildError(context, animate);
}

View file

@ -148,9 +148,7 @@ class EntryActionDelegate with FeedbackMixin, PermissionAwareMixin, SizeAwareMix
switch (action) {
case EntryAction.rotateCCW:
case EntryAction.rotateCW:
return targetEntry.canRotate;
case EntryAction.flip:
return targetEntry.canFlip;
case EntryAction.editDate:
case EntryAction.editLocation:
case EntryAction.editTitleDescription:
@ -163,6 +161,7 @@ class EntryActionDelegate with FeedbackMixin, PermissionAwareMixin, SizeAwareMix
case EntryAction.viewMotionPhotoVideo:
return _metadataActionDelegate.canApply(targetEntry, action);
case EntryAction.convert:
case EntryAction.rename:
case EntryAction.copy:
case EntryAction.move:
return !availability.isLocked;

View file

@ -67,6 +67,11 @@ class EntryInfoActionDelegate with FeedbackMixin, PermissionAwareMixin, EntryEdi
bool canApply(AvesEntry targetEntry, EntryAction action) {
switch (action) {
// general
case EntryAction.rotateCCW:
case EntryAction.rotateCW:
return targetEntry.canRotate;
case EntryAction.flip:
return targetEntry.canFlip;
case EntryAction.editDate:
return targetEntry.canEditDate;
case EntryAction.editLocation:
@ -78,15 +83,15 @@ class EntryInfoActionDelegate with FeedbackMixin, PermissionAwareMixin, EntryEdi
case EntryAction.editTags:
return targetEntry.canEditTags;
case EntryAction.removeMetadata:
return targetEntry.canRemoveMetadata;
return targetEntry.canEdit && targetEntry.isMetadataRemovalSupported;
case EntryAction.exportMetadata:
return true;
return !availability.isLocked;
// GeoTIFF
case EntryAction.showGeoTiffOnMap:
return true;
// motion photo
case EntryAction.convertMotionPhotoToStillImage:
return targetEntry.canEditXmp;
return targetEntry.canEdit && targetEntry.isXmpEditionSupported;
case EntryAction.viewMotionPhotoVideo:
return true;
default:

View file

@ -139,7 +139,7 @@ class WallpaperButtons extends StatelessWidget with FeedbackMixin {
provider = MemoryImage(bytes);
}
}
} else if (entry.canDecode) {
} else if (entry.isDecodingSupported) {
if (entry.useTiles) {
// provider image is already cropped, but not rotated
needOrientation = rotationDegrees != 0 || isFlipped;

View file

@ -127,7 +127,7 @@ class _EntryPageViewState extends State<EntryPageView> with TickerProviderStateM
} else if (!entry.displaySize.isEmpty) {
if (entry.isVideo) {
child = _buildVideoView();
} else if (entry.canDecode) {
} else if (entry.isDecodingSupported) {
child = _buildRasterView();
}
}