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

View file

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

View file

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

View file

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

View file

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

View file

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