parent
68ed8adc98
commit
5b960d0a90
31 changed files with 865 additions and 242 deletions
|
@ -6,7 +6,8 @@ All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- Collection / Info: edit MP4 metadata (date / location / title / description / rating / tags / rotation)
|
- Info: edit MP4 metadata (date / location / title / description / rating / tags / rotation)
|
||||||
|
- Info: edit location by copying from other item
|
||||||
- Widget: option to open collection on tap
|
- Widget: option to open collection on tap
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
|
@ -423,8 +423,8 @@
|
||||||
"@durationDialogMinutes": {},
|
"@durationDialogMinutes": {},
|
||||||
"editEntryLocationDialogTitle": "Standort",
|
"editEntryLocationDialogTitle": "Standort",
|
||||||
"@editEntryLocationDialogTitle": {},
|
"@editEntryLocationDialogTitle": {},
|
||||||
"editEntryLocationDialogChooseOnMapTooltip": "Auf Karte wählen",
|
"editEntryLocationDialogChooseOnMap": "Auf Karte wählen",
|
||||||
"@editEntryLocationDialogChooseOnMapTooltip": {},
|
"@editEntryLocationDialogChooseOnMap": {},
|
||||||
"editEntryLocationDialogLatitude": "Breitengrad",
|
"editEntryLocationDialogLatitude": "Breitengrad",
|
||||||
"@editEntryLocationDialogLatitude": {},
|
"@editEntryLocationDialogLatitude": {},
|
||||||
"editEntryLocationDialogLongitude": "Längengrad",
|
"editEntryLocationDialogLongitude": "Längengrad",
|
||||||
|
|
|
@ -423,8 +423,8 @@
|
||||||
"@durationDialogMinutes": {},
|
"@durationDialogMinutes": {},
|
||||||
"editEntryLocationDialogTitle": "Τοποθεσια",
|
"editEntryLocationDialogTitle": "Τοποθεσια",
|
||||||
"@editEntryLocationDialogTitle": {},
|
"@editEntryLocationDialogTitle": {},
|
||||||
"editEntryLocationDialogChooseOnMapTooltip": "Επιλογή στο χάρτη",
|
"editEntryLocationDialogChooseOnMap": "Επιλογή στο χάρτη",
|
||||||
"@editEntryLocationDialogChooseOnMapTooltip": {},
|
"@editEntryLocationDialogChooseOnMap": {},
|
||||||
"editEntryLocationDialogLatitude": "Γεωγραφικό πλάτος",
|
"editEntryLocationDialogLatitude": "Γεωγραφικό πλάτος",
|
||||||
"@editEntryLocationDialogLatitude": {},
|
"@editEntryLocationDialogLatitude": {},
|
||||||
"editEntryLocationDialogLongitude": "Γεωγραφικό μήκος",
|
"editEntryLocationDialogLongitude": "Γεωγραφικό μήκος",
|
||||||
|
|
|
@ -389,7 +389,8 @@
|
||||||
"durationDialogSeconds": "Seconds",
|
"durationDialogSeconds": "Seconds",
|
||||||
|
|
||||||
"editEntryLocationDialogTitle": "Location",
|
"editEntryLocationDialogTitle": "Location",
|
||||||
"editEntryLocationDialogChooseOnMapTooltip": "Choose on map",
|
"editEntryLocationDialogSetCustom": "Set custom location",
|
||||||
|
"editEntryLocationDialogChooseOnMap": "Choose on map",
|
||||||
"editEntryLocationDialogLatitude": "Latitude",
|
"editEntryLocationDialogLatitude": "Latitude",
|
||||||
"editEntryLocationDialogLongitude": "Longitude",
|
"editEntryLocationDialogLongitude": "Longitude",
|
||||||
|
|
||||||
|
|
|
@ -405,8 +405,8 @@
|
||||||
"@durationDialogMinutes": {},
|
"@durationDialogMinutes": {},
|
||||||
"editEntryLocationDialogTitle": "Ubicación",
|
"editEntryLocationDialogTitle": "Ubicación",
|
||||||
"@editEntryLocationDialogTitle": {},
|
"@editEntryLocationDialogTitle": {},
|
||||||
"editEntryLocationDialogChooseOnMapTooltip": "Elegir en el mapa",
|
"editEntryLocationDialogChooseOnMap": "Elegir en el mapa",
|
||||||
"@editEntryLocationDialogChooseOnMapTooltip": {},
|
"@editEntryLocationDialogChooseOnMap": {},
|
||||||
"editEntryLocationDialogLatitude": "Latitud",
|
"editEntryLocationDialogLatitude": "Latitud",
|
||||||
"@editEntryLocationDialogLatitude": {},
|
"@editEntryLocationDialogLatitude": {},
|
||||||
"editEntryLocationDialogLongitude": "Longitud",
|
"editEntryLocationDialogLongitude": "Longitud",
|
||||||
|
|
|
@ -427,8 +427,8 @@
|
||||||
"@durationDialogSeconds": {},
|
"@durationDialogSeconds": {},
|
||||||
"editEntryLocationDialogTitle": "Lieu",
|
"editEntryLocationDialogTitle": "Lieu",
|
||||||
"@editEntryLocationDialogTitle": {},
|
"@editEntryLocationDialogTitle": {},
|
||||||
"editEntryLocationDialogChooseOnMapTooltip": "Sélectionner sur la carte",
|
"editEntryLocationDialogChooseOnMap": "Sélectionner sur la carte",
|
||||||
"@editEntryLocationDialogChooseOnMapTooltip": {},
|
"@editEntryLocationDialogChooseOnMap": {},
|
||||||
"editEntryLocationDialogLatitude": "Latitude",
|
"editEntryLocationDialogLatitude": "Latitude",
|
||||||
"@editEntryLocationDialogLatitude": {},
|
"@editEntryLocationDialogLatitude": {},
|
||||||
"editEntryLocationDialogLongitude": "Longitude",
|
"editEntryLocationDialogLongitude": "Longitude",
|
||||||
|
|
|
@ -413,8 +413,8 @@
|
||||||
"@durationDialogMinutes": {},
|
"@durationDialogMinutes": {},
|
||||||
"editEntryLocationDialogTitle": "Lokasi",
|
"editEntryLocationDialogTitle": "Lokasi",
|
||||||
"@editEntryLocationDialogTitle": {},
|
"@editEntryLocationDialogTitle": {},
|
||||||
"editEntryLocationDialogChooseOnMapTooltip": "Pilih di peta",
|
"editEntryLocationDialogChooseOnMap": "Pilih di peta",
|
||||||
"@editEntryLocationDialogChooseOnMapTooltip": {},
|
"@editEntryLocationDialogChooseOnMap": {},
|
||||||
"editEntryLocationDialogLatitude": "Garis lintang",
|
"editEntryLocationDialogLatitude": "Garis lintang",
|
||||||
"@editEntryLocationDialogLatitude": {},
|
"@editEntryLocationDialogLatitude": {},
|
||||||
"editEntryLocationDialogLongitude": "Garis bujur",
|
"editEntryLocationDialogLongitude": "Garis bujur",
|
||||||
|
|
|
@ -423,8 +423,8 @@
|
||||||
"@durationDialogMinutes": {},
|
"@durationDialogMinutes": {},
|
||||||
"editEntryLocationDialogTitle": "Posizione",
|
"editEntryLocationDialogTitle": "Posizione",
|
||||||
"@editEntryLocationDialogTitle": {},
|
"@editEntryLocationDialogTitle": {},
|
||||||
"editEntryLocationDialogChooseOnMapTooltip": "Scegli sulla mappa",
|
"editEntryLocationDialogChooseOnMap": "Scegli sulla mappa",
|
||||||
"@editEntryLocationDialogChooseOnMapTooltip": {},
|
"@editEntryLocationDialogChooseOnMap": {},
|
||||||
"editEntryLocationDialogLatitude": "Latitudine",
|
"editEntryLocationDialogLatitude": "Latitudine",
|
||||||
"@editEntryLocationDialogLatitude": {},
|
"@editEntryLocationDialogLatitude": {},
|
||||||
"editEntryLocationDialogLongitude": "Longitudine",
|
"editEntryLocationDialogLongitude": "Longitudine",
|
||||||
|
|
|
@ -405,8 +405,8 @@
|
||||||
"@durationDialogMinutes": {},
|
"@durationDialogMinutes": {},
|
||||||
"editEntryLocationDialogTitle": "位置情報",
|
"editEntryLocationDialogTitle": "位置情報",
|
||||||
"@editEntryLocationDialogTitle": {},
|
"@editEntryLocationDialogTitle": {},
|
||||||
"editEntryLocationDialogChooseOnMapTooltip": "地図上で選択",
|
"editEntryLocationDialogChooseOnMap": "地図上で選択",
|
||||||
"@editEntryLocationDialogChooseOnMapTooltip": {},
|
"@editEntryLocationDialogChooseOnMap": {},
|
||||||
"editEntryLocationDialogLatitude": "緯度",
|
"editEntryLocationDialogLatitude": "緯度",
|
||||||
"@editEntryLocationDialogLatitude": {},
|
"@editEntryLocationDialogLatitude": {},
|
||||||
"editEntryLocationDialogLongitude": "経度",
|
"editEntryLocationDialogLongitude": "経度",
|
||||||
|
|
|
@ -427,8 +427,8 @@
|
||||||
"@durationDialogSeconds": {},
|
"@durationDialogSeconds": {},
|
||||||
"editEntryLocationDialogTitle": "위치",
|
"editEntryLocationDialogTitle": "위치",
|
||||||
"@editEntryLocationDialogTitle": {},
|
"@editEntryLocationDialogTitle": {},
|
||||||
"editEntryLocationDialogChooseOnMapTooltip": "지도에서 선택",
|
"editEntryLocationDialogChooseOnMap": "지도에서 선택",
|
||||||
"@editEntryLocationDialogChooseOnMapTooltip": {},
|
"@editEntryLocationDialogChooseOnMap": {},
|
||||||
"editEntryLocationDialogLatitude": "위도",
|
"editEntryLocationDialogLatitude": "위도",
|
||||||
"@editEntryLocationDialogLatitude": {},
|
"@editEntryLocationDialogLatitude": {},
|
||||||
"editEntryLocationDialogLongitude": "경도",
|
"editEntryLocationDialogLongitude": "경도",
|
||||||
|
|
|
@ -549,8 +549,8 @@
|
||||||
"@editEntryDialogCopyFromItem": {},
|
"@editEntryDialogCopyFromItem": {},
|
||||||
"durationDialogMinutes": "Minutter",
|
"durationDialogMinutes": "Minutter",
|
||||||
"@durationDialogMinutes": {},
|
"@durationDialogMinutes": {},
|
||||||
"editEntryLocationDialogChooseOnMapTooltip": "Velg på kartet",
|
"editEntryLocationDialogChooseOnMap": "Velg på kartet",
|
||||||
"@editEntryLocationDialogChooseOnMapTooltip": {},
|
"@editEntryLocationDialogChooseOnMap": {},
|
||||||
"editEntryRatingDialogTitle": "Vurdering",
|
"editEntryRatingDialogTitle": "Vurdering",
|
||||||
"@editEntryRatingDialogTitle": {},
|
"@editEntryRatingDialogTitle": {},
|
||||||
"removeEntryMetadataDialogTitle": "Metadatafjerning",
|
"removeEntryMetadataDialogTitle": "Metadatafjerning",
|
||||||
|
|
|
@ -421,8 +421,8 @@
|
||||||
"@durationDialogMinutes": {},
|
"@durationDialogMinutes": {},
|
||||||
"editEntryLocationDialogTitle": "Locatie",
|
"editEntryLocationDialogTitle": "Locatie",
|
||||||
"@editEntryLocationDialogTitle": {},
|
"@editEntryLocationDialogTitle": {},
|
||||||
"editEntryLocationDialogChooseOnMapTooltip": "Kies op kaart",
|
"editEntryLocationDialogChooseOnMap": "Kies op kaart",
|
||||||
"@editEntryLocationDialogChooseOnMapTooltip": {},
|
"@editEntryLocationDialogChooseOnMap": {},
|
||||||
"editEntryLocationDialogLatitude": "Breedtegraad",
|
"editEntryLocationDialogLatitude": "Breedtegraad",
|
||||||
"@editEntryLocationDialogLatitude": {},
|
"@editEntryLocationDialogLatitude": {},
|
||||||
"editEntryLocationDialogLongitude": "Lengtegraad",
|
"editEntryLocationDialogLongitude": "Lengtegraad",
|
||||||
|
|
|
@ -423,8 +423,8 @@
|
||||||
"@durationDialogMinutes": {},
|
"@durationDialogMinutes": {},
|
||||||
"editEntryLocationDialogTitle": "Localização",
|
"editEntryLocationDialogTitle": "Localização",
|
||||||
"@editEntryLocationDialogTitle": {},
|
"@editEntryLocationDialogTitle": {},
|
||||||
"editEntryLocationDialogChooseOnMapTooltip": "Escolha no mapa",
|
"editEntryLocationDialogChooseOnMap": "Escolha no mapa",
|
||||||
"@editEntryLocationDialogChooseOnMapTooltip": {},
|
"@editEntryLocationDialogChooseOnMap": {},
|
||||||
"editEntryLocationDialogLatitude": "Latitude",
|
"editEntryLocationDialogLatitude": "Latitude",
|
||||||
"@editEntryLocationDialogLatitude": {},
|
"@editEntryLocationDialogLatitude": {},
|
||||||
"editEntryLocationDialogLongitude": "Longitude",
|
"editEntryLocationDialogLongitude": "Longitude",
|
||||||
|
|
|
@ -423,8 +423,8 @@
|
||||||
"@durationDialogMinutes": {},
|
"@durationDialogMinutes": {},
|
||||||
"editEntryLocationDialogTitle": "Местоположение",
|
"editEntryLocationDialogTitle": "Местоположение",
|
||||||
"@editEntryLocationDialogTitle": {},
|
"@editEntryLocationDialogTitle": {},
|
||||||
"editEntryLocationDialogChooseOnMapTooltip": "Выбрать на карте",
|
"editEntryLocationDialogChooseOnMap": "Выбрать на карте",
|
||||||
"@editEntryLocationDialogChooseOnMapTooltip": {},
|
"@editEntryLocationDialogChooseOnMap": {},
|
||||||
"editEntryLocationDialogLatitude": "Широта",
|
"editEntryLocationDialogLatitude": "Широта",
|
||||||
"@editEntryLocationDialogLatitude": {},
|
"@editEntryLocationDialogLatitude": {},
|
||||||
"editEntryLocationDialogLongitude": "Долгота",
|
"editEntryLocationDialogLongitude": "Долгота",
|
||||||
|
|
|
@ -379,8 +379,8 @@
|
||||||
"@durationDialogMinutes": {},
|
"@durationDialogMinutes": {},
|
||||||
"editEntryLocationDialogTitle": "Konum",
|
"editEntryLocationDialogTitle": "Konum",
|
||||||
"@editEntryLocationDialogTitle": {},
|
"@editEntryLocationDialogTitle": {},
|
||||||
"editEntryLocationDialogChooseOnMapTooltip": "Harita üzerinde seç",
|
"editEntryLocationDialogChooseOnMap": "Harita üzerinde seç",
|
||||||
"@editEntryLocationDialogChooseOnMapTooltip": {},
|
"@editEntryLocationDialogChooseOnMap": {},
|
||||||
"editEntryLocationDialogLatitude": "Enlem",
|
"editEntryLocationDialogLatitude": "Enlem",
|
||||||
"@editEntryLocationDialogLatitude": {},
|
"@editEntryLocationDialogLatitude": {},
|
||||||
"editEntryLocationDialogLongitude": "Boylam",
|
"editEntryLocationDialogLongitude": "Boylam",
|
||||||
|
|
|
@ -423,8 +423,8 @@
|
||||||
"@durationDialogMinutes": {},
|
"@durationDialogMinutes": {},
|
||||||
"editEntryLocationDialogTitle": "位置",
|
"editEntryLocationDialogTitle": "位置",
|
||||||
"@editEntryLocationDialogTitle": {},
|
"@editEntryLocationDialogTitle": {},
|
||||||
"editEntryLocationDialogChooseOnMapTooltip": "从地图上选择",
|
"editEntryLocationDialogChooseOnMap": "从地图上选择",
|
||||||
"@editEntryLocationDialogChooseOnMapTooltip": {},
|
"@editEntryLocationDialogChooseOnMap": {},
|
||||||
"editEntryLocationDialogLatitude": "纬度",
|
"editEntryLocationDialogLatitude": "纬度",
|
||||||
"@editEntryLocationDialogLatitude": {},
|
"@editEntryLocationDialogLatitude": {},
|
||||||
"editEntryLocationDialogLongitude": "经度",
|
"editEntryLocationDialogLongitude": "经度",
|
||||||
|
|
|
@ -3,7 +3,8 @@ import 'dart:io';
|
||||||
|
|
||||||
import 'package:aves/model/entry.dart';
|
import 'package:aves/model/entry.dart';
|
||||||
import 'package:aves/model/metadata/date_modifier.dart';
|
import 'package:aves/model/metadata/date_modifier.dart';
|
||||||
import 'package:aves/model/metadata/enums.dart';
|
import 'package:aves/model/metadata/enums/date_field_source.dart';
|
||||||
|
import 'package:aves/model/metadata/enums/enums.dart';
|
||||||
import 'package:aves/model/metadata/fields.dart';
|
import 'package:aves/model/metadata/fields.dart';
|
||||||
import 'package:aves/ref/exif.dart';
|
import 'package:aves/ref/exif.dart';
|
||||||
import 'package:aves/ref/iptc.dart';
|
import 'package:aves/ref/iptc.dart';
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import 'package:aves/model/metadata/enums.dart';
|
import 'package:aves/model/metadata/enums/enums.dart';
|
||||||
import 'package:aves/model/metadata/fields.dart';
|
import 'package:aves/model/metadata/fields.dart';
|
||||||
import 'package:equatable/equatable.dart';
|
import 'package:equatable/equatable.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
|
|
22
lib/model/metadata/enums/date_edit_action.dart
Normal file
22
lib/model/metadata/enums/date_edit_action.dart
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
import 'package:aves/model/metadata/enums/enums.dart';
|
||||||
|
import 'package:aves/widgets/common/extensions/build_context.dart';
|
||||||
|
import 'package:flutter/widgets.dart';
|
||||||
|
|
||||||
|
extension ExtraDateEditAction on DateEditAction {
|
||||||
|
String getText(BuildContext context) {
|
||||||
|
switch (this) {
|
||||||
|
case DateEditAction.setCustom:
|
||||||
|
return context.l10n.editEntryDateDialogSetCustom;
|
||||||
|
case DateEditAction.copyField:
|
||||||
|
return context.l10n.editEntryDateDialogCopyField;
|
||||||
|
case DateEditAction.copyItem:
|
||||||
|
return context.l10n.editEntryDialogCopyFromItem;
|
||||||
|
case DateEditAction.extractFromTitle:
|
||||||
|
return context.l10n.editEntryDateDialogExtractFromTitle;
|
||||||
|
case DateEditAction.shift:
|
||||||
|
return context.l10n.editEntryDateDialogShift;
|
||||||
|
case DateEditAction.remove:
|
||||||
|
return context.l10n.actionRemove;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
36
lib/model/metadata/enums/date_field_source.dart
Normal file
36
lib/model/metadata/enums/date_field_source.dart
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
import 'package:aves/model/metadata/enums/enums.dart';
|
||||||
|
import 'package:aves/model/metadata/fields.dart';
|
||||||
|
import 'package:aves/widgets/common/extensions/build_context.dart';
|
||||||
|
import 'package:flutter/widgets.dart';
|
||||||
|
|
||||||
|
extension ExtraDateFieldSource on DateFieldSource {
|
||||||
|
String getText(BuildContext context) {
|
||||||
|
switch (this) {
|
||||||
|
case DateFieldSource.fileModifiedDate:
|
||||||
|
return context.l10n.editEntryDateDialogSourceFileModifiedDate;
|
||||||
|
case DateFieldSource.exifDate:
|
||||||
|
return 'Exif date';
|
||||||
|
case DateFieldSource.exifDateOriginal:
|
||||||
|
return 'Exif original date';
|
||||||
|
case DateFieldSource.exifDateDigitized:
|
||||||
|
return 'Exif digitized date';
|
||||||
|
case DateFieldSource.exifGpsDate:
|
||||||
|
return 'Exif GPS date';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MetadataField? toMetadataField() {
|
||||||
|
switch (this) {
|
||||||
|
case DateFieldSource.fileModifiedDate:
|
||||||
|
return null;
|
||||||
|
case DateFieldSource.exifDate:
|
||||||
|
return MetadataField.exifDate;
|
||||||
|
case DateFieldSource.exifDateOriginal:
|
||||||
|
return MetadataField.exifDateOriginal;
|
||||||
|
case DateFieldSource.exifDateDigitized:
|
||||||
|
return MetadataField.exifDateDigitized;
|
||||||
|
case DateFieldSource.exifGpsDate:
|
||||||
|
return MetadataField.exifGpsDatestamp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
46
lib/model/metadata/enums/enums.dart
Normal file
46
lib/model/metadata/enums/enums.dart
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
enum DateEditAction {
|
||||||
|
setCustom,
|
||||||
|
copyField,
|
||||||
|
copyItem,
|
||||||
|
extractFromTitle,
|
||||||
|
shift,
|
||||||
|
remove,
|
||||||
|
}
|
||||||
|
|
||||||
|
enum DateFieldSource {
|
||||||
|
fileModifiedDate,
|
||||||
|
exifDate,
|
||||||
|
exifDateOriginal,
|
||||||
|
exifDateDigitized,
|
||||||
|
exifGpsDate,
|
||||||
|
}
|
||||||
|
|
||||||
|
enum LocationEditAction {
|
||||||
|
chooseOnMap,
|
||||||
|
copyItem,
|
||||||
|
setCustom,
|
||||||
|
remove,
|
||||||
|
}
|
||||||
|
|
||||||
|
enum MetadataType {
|
||||||
|
// JPEG COM marker or GIF comment
|
||||||
|
comment,
|
||||||
|
// Exif: https://en.wikipedia.org/wiki/Exif
|
||||||
|
exif,
|
||||||
|
// ICC profile: https://en.wikipedia.org/wiki/ICC_profile
|
||||||
|
iccProfile,
|
||||||
|
// IPTC: https://en.wikipedia.org/wiki/IPTC_Information_Interchange_Model
|
||||||
|
iptc,
|
||||||
|
// JPEG APP0 / JFIF: https://en.wikipedia.org/wiki/JPEG_File_Interchange_Format
|
||||||
|
jfif,
|
||||||
|
// JPEG APP14 / Adobe: https://www.exiftool.org/TagNames/JPEG.html#Adobe
|
||||||
|
jpegAdobe,
|
||||||
|
// JPEG APP12 / Ducky: https://www.exiftool.org/TagNames/APP12.html#Ducky
|
||||||
|
jpegDucky,
|
||||||
|
// ISO User Data box content, etc.
|
||||||
|
mp4,
|
||||||
|
// Photoshop IRB: https://www.adobe.com/devnet-apps/photoshop/fileformatashtml/
|
||||||
|
photoshopIrb,
|
||||||
|
// XMP: https://en.wikipedia.org/wiki/Extensible_Metadata_Platform
|
||||||
|
xmp,
|
||||||
|
}
|
18
lib/model/metadata/enums/location_edit_action.dart
Normal file
18
lib/model/metadata/enums/location_edit_action.dart
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
import 'package:aves/model/metadata/enums/enums.dart';
|
||||||
|
import 'package:aves/widgets/common/extensions/build_context.dart';
|
||||||
|
import 'package:flutter/widgets.dart';
|
||||||
|
|
||||||
|
extension ExtraLocationEditAction on LocationEditAction {
|
||||||
|
String getText(BuildContext context) {
|
||||||
|
switch (this) {
|
||||||
|
case LocationEditAction.chooseOnMap:
|
||||||
|
return context.l10n.editEntryLocationDialogChooseOnMap;
|
||||||
|
case LocationEditAction.copyItem:
|
||||||
|
return context.l10n.editEntryDialogCopyFromItem;
|
||||||
|
case LocationEditAction.setCustom:
|
||||||
|
return context.l10n.editEntryLocationDialogSetCustom;
|
||||||
|
case LocationEditAction.remove:
|
||||||
|
return context.l10n.actionRemove;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,44 +1,4 @@
|
||||||
import 'package:aves/model/metadata/fields.dart';
|
import 'package:aves/model/metadata/enums/enums.dart';
|
||||||
|
|
||||||
enum DateEditAction {
|
|
||||||
setCustom,
|
|
||||||
copyField,
|
|
||||||
copyItem,
|
|
||||||
extractFromTitle,
|
|
||||||
shift,
|
|
||||||
remove,
|
|
||||||
}
|
|
||||||
|
|
||||||
enum DateFieldSource {
|
|
||||||
fileModifiedDate,
|
|
||||||
exifDate,
|
|
||||||
exifDateOriginal,
|
|
||||||
exifDateDigitized,
|
|
||||||
exifGpsDate,
|
|
||||||
}
|
|
||||||
|
|
||||||
enum MetadataType {
|
|
||||||
// JPEG COM marker or GIF comment
|
|
||||||
comment,
|
|
||||||
// Exif: https://en.wikipedia.org/wiki/Exif
|
|
||||||
exif,
|
|
||||||
// ICC profile: https://en.wikipedia.org/wiki/ICC_profile
|
|
||||||
iccProfile,
|
|
||||||
// IPTC: https://en.wikipedia.org/wiki/IPTC_Information_Interchange_Model
|
|
||||||
iptc,
|
|
||||||
// JPEG APP0 / JFIF: https://en.wikipedia.org/wiki/JPEG_File_Interchange_Format
|
|
||||||
jfif,
|
|
||||||
// JPEG APP14 / Adobe: https://www.exiftool.org/TagNames/JPEG.html#Adobe
|
|
||||||
jpegAdobe,
|
|
||||||
// JPEG APP12 / Ducky: https://www.exiftool.org/TagNames/APP12.html#Ducky
|
|
||||||
jpegDucky,
|
|
||||||
// ISO User Data box content, etc.
|
|
||||||
mp4,
|
|
||||||
// Photoshop IRB: https://www.adobe.com/devnet-apps/photoshop/fileformatashtml/
|
|
||||||
photoshopIrb,
|
|
||||||
// XMP: https://en.wikipedia.org/wiki/Extensible_Metadata_Platform
|
|
||||||
xmp,
|
|
||||||
}
|
|
||||||
|
|
||||||
class MetadataTypes {
|
class MetadataTypes {
|
||||||
static const main = {
|
static const main = {
|
||||||
|
@ -114,20 +74,3 @@ extension ExtraMetadataType on MetadataType {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension ExtraDateFieldSource on DateFieldSource {
|
|
||||||
MetadataField? toMetadataField() {
|
|
||||||
switch (this) {
|
|
||||||
case DateFieldSource.fileModifiedDate:
|
|
||||||
return null;
|
|
||||||
case DateFieldSource.exifDate:
|
|
||||||
return MetadataField.exifDate;
|
|
||||||
case DateFieldSource.exifDateOriginal:
|
|
||||||
return MetadataField.exifDateOriginal;
|
|
||||||
case DateFieldSource.exifDateDigitized:
|
|
||||||
return MetadataField.exifDateDigitized;
|
|
||||||
case DateFieldSource.exifGpsDate:
|
|
||||||
return MetadataField.exifGpsDatestamp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,4 +1,4 @@
|
||||||
import 'package:aves/model/metadata/enums.dart';
|
import 'package:aves/model/metadata/enums/enums.dart';
|
||||||
|
|
||||||
enum MetadataField {
|
enum MetadataField {
|
||||||
exifDate,
|
exifDate,
|
||||||
|
|
|
@ -2,7 +2,8 @@ import 'dart:async';
|
||||||
|
|
||||||
import 'package:aves/model/entry.dart';
|
import 'package:aves/model/entry.dart';
|
||||||
import 'package:aves/model/metadata/date_modifier.dart';
|
import 'package:aves/model/metadata/date_modifier.dart';
|
||||||
import 'package:aves/model/metadata/enums.dart';
|
import 'package:aves/model/metadata/enums/enums.dart';
|
||||||
|
import 'package:aves/model/metadata/enums/metadata_type.dart';
|
||||||
import 'package:aves/model/metadata/fields.dart';
|
import 'package:aves/model/metadata/fields.dart';
|
||||||
import 'package:aves/services/common/services.dart';
|
import 'package:aves/services/common/services.dart';
|
||||||
import 'package:collection/collection.dart';
|
import 'package:collection/collection.dart';
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import 'package:aves/model/entry.dart';
|
import 'package:aves/model/entry.dart';
|
||||||
import 'package:aves/model/entry_metadata_edition.dart';
|
import 'package:aves/model/entry_metadata_edition.dart';
|
||||||
import 'package:aves/model/metadata/date_modifier.dart';
|
import 'package:aves/model/metadata/date_modifier.dart';
|
||||||
import 'package:aves/model/metadata/enums.dart';
|
import 'package:aves/model/metadata/enums/enums.dart';
|
||||||
import 'package:aves/model/source/collection_lens.dart';
|
import 'package:aves/model/source/collection_lens.dart';
|
||||||
import 'package:aves/ref/mime_types.dart';
|
import 'package:aves/ref/mime_types.dart';
|
||||||
import 'package:aves/services/common/services.dart';
|
import 'package:aves/services/common/services.dart';
|
||||||
|
@ -33,12 +33,12 @@ mixin EntryEditorMixin {
|
||||||
Future<LatLng?> selectLocation(BuildContext context, Set<AvesEntry> entries, CollectionLens? collection) async {
|
Future<LatLng?> selectLocation(BuildContext context, Set<AvesEntry> entries, CollectionLens? collection) async {
|
||||||
if (entries.isEmpty) return null;
|
if (entries.isEmpty) return null;
|
||||||
|
|
||||||
final initialLocation = entries.firstWhereOrNull((entry) => entry.hasGps)?.latLng;
|
final entry = entries.firstWhereOrNull((entry) => entry.hasGps) ?? entries.first;
|
||||||
|
|
||||||
return showDialog<LatLng>(
|
return showDialog<LatLng>(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (context) => EditEntryLocationDialog(
|
builder: (context) => EditEntryLocationDialog(
|
||||||
initialLocation: initialLocation,
|
entry: entry,
|
||||||
collection: collection,
|
collection: collection,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
|
@ -8,7 +8,7 @@ import 'package:aves/model/filters/album.dart';
|
||||||
import 'package:aves/model/filters/trash.dart';
|
import 'package:aves/model/filters/trash.dart';
|
||||||
import 'package:aves/model/highlight.dart';
|
import 'package:aves/model/highlight.dart';
|
||||||
import 'package:aves/model/metadata/date_modifier.dart';
|
import 'package:aves/model/metadata/date_modifier.dart';
|
||||||
import 'package:aves/model/metadata/enums.dart';
|
import 'package:aves/model/metadata/enums/enums.dart';
|
||||||
import 'package:aves/model/settings/enums/enums.dart';
|
import 'package:aves/model/settings/enums/enums.dart';
|
||||||
import 'package:aves/model/settings/settings.dart';
|
import 'package:aves/model/settings/settings.dart';
|
||||||
import 'package:aves/model/source/collection_lens.dart';
|
import 'package:aves/model/source/collection_lens.dart';
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
import 'package:aves/model/entry.dart';
|
import 'package:aves/model/entry.dart';
|
||||||
import 'package:aves/model/metadata/date_modifier.dart';
|
import 'package:aves/model/metadata/date_modifier.dart';
|
||||||
import 'package:aves/model/metadata/enums.dart';
|
import 'package:aves/model/metadata/enums/date_edit_action.dart';
|
||||||
|
import 'package:aves/model/metadata/enums/date_field_source.dart';
|
||||||
|
import 'package:aves/model/metadata/enums/enums.dart';
|
||||||
import 'package:aves/model/metadata/fields.dart';
|
import 'package:aves/model/metadata/fields.dart';
|
||||||
import 'package:aves/model/source/collection_lens.dart';
|
import 'package:aves/model/source/collection_lens.dart';
|
||||||
import 'package:aves/theme/durations.dart';
|
import 'package:aves/theme/durations.dart';
|
||||||
|
@ -36,7 +38,7 @@ class _EditEntryDateDialogState extends State<EditEntryDateDialog> {
|
||||||
DateEditAction _action = DateEditAction.setCustom;
|
DateEditAction _action = DateEditAction.setCustom;
|
||||||
DateFieldSource _copyFieldSource = DateFieldSource.fileModifiedDate;
|
DateFieldSource _copyFieldSource = DateFieldSource.fileModifiedDate;
|
||||||
late AvesEntry _copyItemSource;
|
late AvesEntry _copyItemSource;
|
||||||
late DateTime _setDateTime;
|
late DateTime _customDateTime;
|
||||||
late ValueNotifier<int> _shiftHour, _shiftMinute;
|
late ValueNotifier<int> _shiftHour, _shiftMinute;
|
||||||
late ValueNotifier<String> _shiftSign;
|
late ValueNotifier<String> _shiftSign;
|
||||||
bool _showOptions = false;
|
bool _showOptions = false;
|
||||||
|
@ -47,13 +49,13 @@ class _EditEntryDateDialogState extends State<EditEntryDateDialog> {
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
_initSet();
|
_initCustom();
|
||||||
_initCopyItem();
|
_initCopyItem();
|
||||||
_initShift(minutesInHour);
|
_initShift(minutesInHour);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _initSet() {
|
void _initCustom() {
|
||||||
_setDateTime = widget.entry.bestDate ?? DateTime.now();
|
_customDateTime = widget.entry.bestDate ?? DateTime.now();
|
||||||
}
|
}
|
||||||
|
|
||||||
void _initCopyItem() {
|
void _initCopyItem() {
|
||||||
|
@ -84,7 +86,7 @@ class _EditEntryDateDialogState extends State<EditEntryDateDialog> {
|
||||||
padding: const EdgeInsets.only(left: 16, top: 8, right: 16),
|
padding: const EdgeInsets.only(left: 16, top: 8, right: 16),
|
||||||
child: TextDropdownButton<DateEditAction>(
|
child: TextDropdownButton<DateEditAction>(
|
||||||
values: DateEditAction.values,
|
values: DateEditAction.values,
|
||||||
valueText: (v) => _actionText(context, v),
|
valueText: (v) => v.getText(context),
|
||||||
value: _action,
|
value: _action,
|
||||||
onChanged: (v) => setState(() => _action = v!),
|
onChanged: (v) => setState(() => _action = v!),
|
||||||
isExpanded: true,
|
isExpanded: true,
|
||||||
|
@ -143,7 +145,7 @@ class _EditEntryDateDialogState extends State<EditEntryDateDialog> {
|
||||||
padding: const EdgeInsetsDirectional.only(start: 16, end: 8),
|
padding: const EdgeInsetsDirectional.only(start: 16, end: 8),
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
Expanded(child: Text(formatDateTime(_setDateTime, locale, use24hour))),
|
Expanded(child: Text(formatDateTime(_customDateTime, locale, use24hour))),
|
||||||
IconButton(
|
IconButton(
|
||||||
icon: const Icon(AIcons.edit),
|
icon: const Icon(AIcons.edit),
|
||||||
onPressed: _editDate,
|
onPressed: _editDate,
|
||||||
|
@ -159,7 +161,7 @@ class _EditEntryDateDialogState extends State<EditEntryDateDialog> {
|
||||||
padding: const EdgeInsets.only(left: 16, top: 0, right: 16),
|
padding: const EdgeInsets.only(left: 16, top: 0, right: 16),
|
||||||
child: TextDropdownButton<DateFieldSource>(
|
child: TextDropdownButton<DateFieldSource>(
|
||||||
values: DateFieldSource.values,
|
values: DateFieldSource.values,
|
||||||
valueText: (v) => _setSourceText(context, v),
|
valueText: (v) => v.getText(context),
|
||||||
value: _copyFieldSource,
|
value: _copyFieldSource,
|
||||||
onChanged: (v) => setState(() => _copyFieldSource = v!),
|
onChanged: (v) => setState(() => _copyFieldSource = v!),
|
||||||
isExpanded: true,
|
isExpanded: true,
|
||||||
|
@ -280,44 +282,10 @@ class _EditEntryDateDialogState extends State<EditEntryDateDialog> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
String _actionText(BuildContext context, DateEditAction action) {
|
|
||||||
final l10n = context.l10n;
|
|
||||||
switch (action) {
|
|
||||||
case DateEditAction.setCustom:
|
|
||||||
return l10n.editEntryDateDialogSetCustom;
|
|
||||||
case DateEditAction.copyField:
|
|
||||||
return l10n.editEntryDateDialogCopyField;
|
|
||||||
case DateEditAction.copyItem:
|
|
||||||
return l10n.editEntryDialogCopyFromItem;
|
|
||||||
case DateEditAction.extractFromTitle:
|
|
||||||
return l10n.editEntryDateDialogExtractFromTitle;
|
|
||||||
case DateEditAction.shift:
|
|
||||||
return l10n.editEntryDateDialogShift;
|
|
||||||
case DateEditAction.remove:
|
|
||||||
return l10n.actionRemove;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
String _setSourceText(BuildContext context, DateFieldSource source) {
|
|
||||||
final l10n = context.l10n;
|
|
||||||
switch (source) {
|
|
||||||
case DateFieldSource.fileModifiedDate:
|
|
||||||
return l10n.editEntryDateDialogSourceFileModifiedDate;
|
|
||||||
case DateFieldSource.exifDate:
|
|
||||||
return 'Exif date';
|
|
||||||
case DateFieldSource.exifDateOriginal:
|
|
||||||
return 'Exif original date';
|
|
||||||
case DateFieldSource.exifDateDigitized:
|
|
||||||
return 'Exif digitized date';
|
|
||||||
case DateFieldSource.exifGpsDate:
|
|
||||||
return 'Exif GPS date';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> _editDate() async {
|
Future<void> _editDate() async {
|
||||||
final _date = await showDatePicker(
|
final _date = await showDatePicker(
|
||||||
context: context,
|
context: context,
|
||||||
initialDate: _setDateTime,
|
initialDate: _customDateTime,
|
||||||
firstDate: DateTime(0),
|
firstDate: DateTime(0),
|
||||||
lastDate: DateTime(2100),
|
lastDate: DateTime(2100),
|
||||||
confirmText: context.l10n.nextButtonLabel,
|
confirmText: context.l10n.nextButtonLabel,
|
||||||
|
@ -326,11 +294,11 @@ class _EditEntryDateDialogState extends State<EditEntryDateDialog> {
|
||||||
|
|
||||||
final _time = await showTimePicker(
|
final _time = await showTimePicker(
|
||||||
context: context,
|
context: context,
|
||||||
initialTime: TimeOfDay.fromDateTime(_setDateTime),
|
initialTime: TimeOfDay.fromDateTime(_customDateTime),
|
||||||
);
|
);
|
||||||
if (_time == null) return;
|
if (_time == null) return;
|
||||||
|
|
||||||
setState(() => _setDateTime = DateTime(
|
setState(() => _customDateTime = DateTime(
|
||||||
_date.year,
|
_date.year,
|
||||||
_date.month,
|
_date.month,
|
||||||
_date.day,
|
_date.day,
|
||||||
|
@ -366,7 +334,7 @@ class _EditEntryDateDialogState extends State<EditEntryDateDialog> {
|
||||||
// whether each item supports Exif edition
|
// whether each item supports Exif edition
|
||||||
switch (_action) {
|
switch (_action) {
|
||||||
case DateEditAction.setCustom:
|
case DateEditAction.setCustom:
|
||||||
return DateModifier.setCustom(const {}, _setDateTime);
|
return DateModifier.setCustom(const {}, _customDateTime);
|
||||||
case DateEditAction.copyField:
|
case DateEditAction.copyField:
|
||||||
return DateModifier.copyField(_copyFieldSource);
|
return DateModifier.copyField(_copyFieldSource);
|
||||||
case DateEditAction.copyItem:
|
case DateEditAction.copyItem:
|
||||||
|
|
|
@ -1,22 +1,32 @@
|
||||||
|
import 'package:aves/model/entry.dart';
|
||||||
|
import 'package:aves/model/metadata/enums/enums.dart';
|
||||||
|
import 'package:aves/model/metadata/enums/location_edit_action.dart';
|
||||||
|
import 'package:aves/model/settings/enums/coordinate_format.dart';
|
||||||
import 'package:aves/model/settings/settings.dart';
|
import 'package:aves/model/settings/settings.dart';
|
||||||
import 'package:aves/model/source/collection_lens.dart';
|
import 'package:aves/model/source/collection_lens.dart';
|
||||||
|
import 'package:aves/theme/durations.dart';
|
||||||
import 'package:aves/theme/icons.dart';
|
import 'package:aves/theme/icons.dart';
|
||||||
|
import 'package:aves/theme/themes.dart';
|
||||||
import 'package:aves/utils/constants.dart';
|
import 'package:aves/utils/constants.dart';
|
||||||
|
import 'package:aves/widgets/common/basic/text_dropdown_button.dart';
|
||||||
import 'package:aves/widgets/common/extensions/build_context.dart';
|
import 'package:aves/widgets/common/extensions/build_context.dart';
|
||||||
import 'package:aves/widgets/common/providers/media_query_data_provider.dart';
|
import 'package:aves/widgets/common/providers/media_query_data_provider.dart';
|
||||||
import 'package:aves/widgets/dialogs/aves_dialog.dart';
|
import 'package:aves/widgets/dialogs/aves_dialog.dart';
|
||||||
|
import 'package:aves/widgets/dialogs/item_pick_dialog.dart';
|
||||||
|
import 'package:aves/widgets/dialogs/item_picker.dart';
|
||||||
import 'package:aves/widgets/dialogs/location_pick_dialog.dart';
|
import 'package:aves/widgets/dialogs/location_pick_dialog.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:intl/intl.dart';
|
import 'package:intl/intl.dart';
|
||||||
import 'package:latlong2/latlong.dart';
|
import 'package:latlong2/latlong.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
class EditEntryLocationDialog extends StatefulWidget {
|
class EditEntryLocationDialog extends StatefulWidget {
|
||||||
final LatLng? initialLocation;
|
final AvesEntry entry;
|
||||||
final CollectionLens? collection;
|
final CollectionLens? collection;
|
||||||
|
|
||||||
const EditEntryLocationDialog({
|
const EditEntryLocationDialog({
|
||||||
super.key,
|
super.key,
|
||||||
required this.initialLocation,
|
required this.entry,
|
||||||
this.collection,
|
this.collection,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -25,9 +35,10 @@ class EditEntryLocationDialog extends StatefulWidget {
|
||||||
}
|
}
|
||||||
|
|
||||||
class _EditEntryLocationDialogState extends State<EditEntryLocationDialog> {
|
class _EditEntryLocationDialogState extends State<EditEntryLocationDialog> {
|
||||||
_LocationAction _action = _LocationAction.set;
|
LocationEditAction _action = LocationEditAction.chooseOnMap;
|
||||||
|
LatLng? _mapCoordinates;
|
||||||
|
late AvesEntry _copyItemSource;
|
||||||
final TextEditingController _latitudeController = TextEditingController(), _longitudeController = TextEditingController();
|
final TextEditingController _latitudeController = TextEditingController(), _longitudeController = TextEditingController();
|
||||||
final FocusNode _latitudeFocusNode = FocusNode(), _longitudeFocusNode = FocusNode();
|
|
||||||
final ValueNotifier<bool> _isValidNotifier = ValueNotifier(false);
|
final ValueNotifier<bool> _isValidNotifier = ValueNotifier(false);
|
||||||
|
|
||||||
NumberFormat get coordinateFormatter => NumberFormat('0.000000', context.l10n.localeName);
|
NumberFormat get coordinateFormatter => NumberFormat('0.000000', context.l10n.localeName);
|
||||||
|
@ -35,15 +46,35 @@ class _EditEntryLocationDialogState extends State<EditEntryLocationDialog> {
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
_latitudeFocusNode.addListener(_onLatLngFocusChange);
|
_initMapCoordinates();
|
||||||
_longitudeFocusNode.addListener(_onLatLngFocusChange);
|
_initCopyItem();
|
||||||
WidgetsBinding.instance.addPostFrameCallback((_) => _setLocation(context, widget.initialLocation));
|
_initCustom();
|
||||||
|
}
|
||||||
|
|
||||||
|
void _initMapCoordinates() {
|
||||||
|
_mapCoordinates = widget.entry.latLng;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _initCopyItem() {
|
||||||
|
_copyItemSource = widget.entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _initCustom() {
|
||||||
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
|
final latLng = widget.entry.latLng;
|
||||||
|
if (latLng != null) {
|
||||||
|
_latitudeController.text = coordinateFormatter.format(latLng.latitude);
|
||||||
|
_longitudeController.text = coordinateFormatter.format(latLng.longitude);
|
||||||
|
} else {
|
||||||
|
_latitudeController.text = '';
|
||||||
|
_longitudeController.text = '';
|
||||||
|
}
|
||||||
|
setState(_validate);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
_latitudeFocusNode.removeListener(_onLatLngFocusChange);
|
|
||||||
_longitudeFocusNode.removeListener(_onLatLngFocusChange);
|
|
||||||
_latitudeController.dispose();
|
_latitudeController.dispose();
|
||||||
_longitudeController.dispose();
|
_longitudeController.dispose();
|
||||||
super.dispose();
|
super.dispose();
|
||||||
|
@ -62,64 +93,36 @@ class _EditEntryLocationDialogState extends State<EditEntryLocationDialog> {
|
||||||
return AvesDialog(
|
return AvesDialog(
|
||||||
title: l10n.editEntryLocationDialogTitle,
|
title: l10n.editEntryLocationDialogTitle,
|
||||||
scrollableContent: [
|
scrollableContent: [
|
||||||
RadioListTile<_LocationAction>(
|
Padding(
|
||||||
value: _LocationAction.set,
|
padding: const EdgeInsets.only(left: 16, top: 8, right: 16),
|
||||||
groupValue: _action,
|
child: TextDropdownButton<LocationEditAction>(
|
||||||
onChanged: (v) => setState(() {
|
values: LocationEditAction.values,
|
||||||
_action = v!;
|
valueText: (v) => v.getText(context),
|
||||||
_validate();
|
value: _action,
|
||||||
}),
|
onChanged: (v) => setState(() {
|
||||||
title: Row(
|
_action = v!;
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
_validate();
|
||||||
|
}),
|
||||||
|
isExpanded: true,
|
||||||
|
dropdownColor: Themes.thirdLayerColor(context),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
AnimatedSwitcher(
|
||||||
|
duration: context.read<DurationsData>().formTransition,
|
||||||
|
switchInCurve: Curves.easeInOutCubic,
|
||||||
|
switchOutCurve: Curves.easeInOutCubic,
|
||||||
|
transitionBuilder: _formTransitionBuilder,
|
||||||
|
child: Column(
|
||||||
|
key: ValueKey(_action),
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
Expanded(
|
if (_action == LocationEditAction.chooseOnMap) _buildChooseOnMapContent(context),
|
||||||
child: Column(
|
if (_action == LocationEditAction.copyItem) _buildCopyItemContent(context),
|
||||||
children: [
|
if (_action == LocationEditAction.setCustom) _buildSetCustomContent(context),
|
||||||
TextField(
|
|
||||||
controller: _latitudeController,
|
|
||||||
focusNode: _latitudeFocusNode,
|
|
||||||
decoration: InputDecoration(
|
|
||||||
labelText: l10n.editEntryLocationDialogLatitude,
|
|
||||||
hintText: coordinateFormatter.format(Constants.pointNemo.latitude),
|
|
||||||
),
|
|
||||||
onChanged: (_) => _validate(),
|
|
||||||
),
|
|
||||||
TextField(
|
|
||||||
controller: _longitudeController,
|
|
||||||
focusNode: _longitudeFocusNode,
|
|
||||||
decoration: InputDecoration(
|
|
||||||
labelText: l10n.editEntryLocationDialogLongitude,
|
|
||||||
hintText: coordinateFormatter.format(Constants.pointNemo.longitude),
|
|
||||||
),
|
|
||||||
onChanged: (_) => _validate(),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(width: 8),
|
|
||||||
Padding(
|
|
||||||
padding: const EdgeInsets.only(top: 8.0),
|
|
||||||
child: IconButton(
|
|
||||||
icon: const Icon(AIcons.map),
|
|
||||||
onPressed: _pickLocation,
|
|
||||||
tooltip: l10n.editEntryLocationDialogChooseOnMapTooltip,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
contentPadding: const EdgeInsetsDirectional.only(start: 16, end: 8),
|
|
||||||
),
|
|
||||||
RadioListTile<_LocationAction>(
|
|
||||||
value: _LocationAction.remove,
|
|
||||||
groupValue: _action,
|
|
||||||
onChanged: (v) => setState(() {
|
|
||||||
_action = v!;
|
|
||||||
_latitudeFocusNode.unfocus();
|
|
||||||
_longitudeFocusNode.unfocus();
|
|
||||||
_validate();
|
|
||||||
}),
|
|
||||||
title: Text(l10n.actionRemove),
|
|
||||||
),
|
),
|
||||||
|
const SizedBox(height: 8),
|
||||||
],
|
],
|
||||||
actions: [
|
actions: [
|
||||||
TextButton(
|
TextButton(
|
||||||
|
@ -142,22 +145,32 @@ class _EditEntryLocationDialogState extends State<EditEntryLocationDialog> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _onLatLngFocusChange() {
|
Widget _formTransitionBuilder(Widget child, Animation<double> animation) => FadeTransition(
|
||||||
if (_latitudeFocusNode.hasFocus || _longitudeFocusNode.hasFocus) {
|
opacity: animation,
|
||||||
setState(() {
|
child: SizeTransition(
|
||||||
_action = _LocationAction.set;
|
sizeFactor: animation,
|
||||||
_validate();
|
axisAlignment: -1,
|
||||||
});
|
child: child,
|
||||||
}
|
),
|
||||||
}
|
);
|
||||||
|
|
||||||
void _setLocation(BuildContext context, LatLng? latLng) {
|
Widget _buildChooseOnMapContent(BuildContext context) {
|
||||||
_latitudeController.text = latLng != null ? coordinateFormatter.format(latLng.latitude) : '';
|
final l10n = context.l10n;
|
||||||
_longitudeController.text = latLng != null ? coordinateFormatter.format(latLng.longitude) : '';
|
|
||||||
setState(() {
|
return Padding(
|
||||||
_action = _LocationAction.set;
|
padding: const EdgeInsetsDirectional.only(start: 16, end: 8),
|
||||||
_validate();
|
child: Row(
|
||||||
});
|
children: [
|
||||||
|
Expanded(child: _toText(context, _mapCoordinates)),
|
||||||
|
const SizedBox(width: 8),
|
||||||
|
IconButton(
|
||||||
|
icon: const Icon(AIcons.map),
|
||||||
|
onPressed: _pickLocation,
|
||||||
|
tooltip: l10n.editEntryLocationDialogChooseOnMap,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _pickLocation() async {
|
Future<void> _pickLocation() async {
|
||||||
|
@ -176,7 +189,7 @@ class _EditEntryLocationDialogState extends State<EditEntryLocationDialog> {
|
||||||
: null;
|
: null;
|
||||||
return LocationPickDialog(
|
return LocationPickDialog(
|
||||||
collection: mapCollection,
|
collection: mapCollection,
|
||||||
initialLocation: _parseLatLng(),
|
initialLocation: _mapCoordinates,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
fullscreenDialog: true,
|
fullscreenDialog: true,
|
||||||
|
@ -184,7 +197,102 @@ class _EditEntryLocationDialogState extends State<EditEntryLocationDialog> {
|
||||||
);
|
);
|
||||||
if (latLng != null) {
|
if (latLng != null) {
|
||||||
settings.mapDefaultCenter = latLng;
|
settings.mapDefaultCenter = latLng;
|
||||||
_setLocation(context, latLng);
|
setState(() {
|
||||||
|
_mapCoordinates = latLng;
|
||||||
|
_validate();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildCopyItemContent(BuildContext context) {
|
||||||
|
return Padding(
|
||||||
|
padding: const EdgeInsetsDirectional.only(start: 16, end: 8),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Expanded(child: _toText(context, _copyItemSource.latLng)),
|
||||||
|
const SizedBox(width: 8),
|
||||||
|
ItemPicker(
|
||||||
|
extent: 48,
|
||||||
|
entry: _copyItemSource,
|
||||||
|
onTap: _pickCopyItemSource,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _pickCopyItemSource() async {
|
||||||
|
final _collection = widget.collection;
|
||||||
|
if (_collection == null) return;
|
||||||
|
|
||||||
|
final entry = await Navigator.push<AvesEntry>(
|
||||||
|
context,
|
||||||
|
MaterialPageRoute(
|
||||||
|
settings: const RouteSettings(name: ItemPickDialog.routeName),
|
||||||
|
builder: (context) => ItemPickDialog(
|
||||||
|
collection: CollectionLens(
|
||||||
|
source: _collection.source,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
fullscreenDialog: true,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
if (entry != null) {
|
||||||
|
setState(() {
|
||||||
|
_copyItemSource = entry;
|
||||||
|
_validate();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildSetCustomContent(BuildContext context) {
|
||||||
|
final l10n = context.l10n;
|
||||||
|
|
||||||
|
return Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||||
|
child: Row(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
TextField(
|
||||||
|
controller: _latitudeController,
|
||||||
|
decoration: InputDecoration(
|
||||||
|
labelText: l10n.editEntryLocationDialogLatitude,
|
||||||
|
hintText: coordinateFormatter.format(Constants.pointNemo.latitude),
|
||||||
|
),
|
||||||
|
onChanged: (_) => _validate(),
|
||||||
|
),
|
||||||
|
TextField(
|
||||||
|
controller: _longitudeController,
|
||||||
|
decoration: InputDecoration(
|
||||||
|
labelText: l10n.editEntryLocationDialogLongitude,
|
||||||
|
hintText: coordinateFormatter.format(Constants.pointNemo.longitude),
|
||||||
|
),
|
||||||
|
onChanged: (_) => _validate(),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Text _toText(BuildContext context, LatLng? latLng) {
|
||||||
|
final l10n = context.l10n;
|
||||||
|
if (latLng != null) {
|
||||||
|
return Text(
|
||||||
|
ExtraCoordinateFormat.toDMS(l10n, latLng).join('\n'),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return Text(
|
||||||
|
l10n.viewerInfoUnknown,
|
||||||
|
style: TextStyle(
|
||||||
|
color: Theme.of(context).textTheme.bodySmall!.color,
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -205,12 +313,18 @@ class _EditEntryLocationDialogState extends State<EditEntryLocationDialog> {
|
||||||
return LatLng(lat, lng);
|
return LatLng(lat, lng);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _validate() async {
|
void _validate() {
|
||||||
switch (_action) {
|
switch (_action) {
|
||||||
case _LocationAction.set:
|
case LocationEditAction.chooseOnMap:
|
||||||
|
_isValidNotifier.value = _mapCoordinates != null;
|
||||||
|
break;
|
||||||
|
case LocationEditAction.copyItem:
|
||||||
|
_isValidNotifier.value = _copyItemSource.hasGps;
|
||||||
|
break;
|
||||||
|
case LocationEditAction.setCustom:
|
||||||
_isValidNotifier.value = _parseLatLng() != null;
|
_isValidNotifier.value = _parseLatLng() != null;
|
||||||
break;
|
break;
|
||||||
case _LocationAction.remove:
|
case LocationEditAction.remove:
|
||||||
_isValidNotifier.value = true;
|
_isValidNotifier.value = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -218,14 +332,18 @@ class _EditEntryLocationDialogState extends State<EditEntryLocationDialog> {
|
||||||
|
|
||||||
void _submit(BuildContext context) {
|
void _submit(BuildContext context) {
|
||||||
switch (_action) {
|
switch (_action) {
|
||||||
case _LocationAction.set:
|
case LocationEditAction.chooseOnMap:
|
||||||
|
Navigator.pop(context, _mapCoordinates);
|
||||||
|
break;
|
||||||
|
case LocationEditAction.copyItem:
|
||||||
|
Navigator.pop(context, _copyItemSource.latLng);
|
||||||
|
break;
|
||||||
|
case LocationEditAction.setCustom:
|
||||||
Navigator.pop(context, _parseLatLng());
|
Navigator.pop(context, _parseLatLng());
|
||||||
break;
|
break;
|
||||||
case _LocationAction.remove:
|
case LocationEditAction.remove:
|
||||||
Navigator.pop(context, LatLng(0, 0));
|
Navigator.pop(context, LatLng(0, 0));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enum _LocationAction { set, remove }
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import 'package:aves/model/metadata/enums.dart';
|
import 'package:aves/model/metadata/enums/enums.dart';
|
||||||
|
import 'package:aves/model/metadata/enums/metadata_type.dart';
|
||||||
import 'package:aves/model/settings/enums/enums.dart';
|
import 'package:aves/model/settings/enums/enums.dart';
|
||||||
import 'package:aves/model/settings/settings.dart';
|
import 'package:aves/model/settings/settings.dart';
|
||||||
import 'package:aves/ref/brand_colors.dart';
|
import 'package:aves/ref/brand_colors.dart';
|
||||||
|
|
|
@ -1,12 +1,17 @@
|
||||||
{
|
{
|
||||||
"de": [
|
"de": [
|
||||||
"widgetOpenPageCollection",
|
"editEntryLocationDialogSetCustom"
|
||||||
"durationDialogSeconds"
|
|
||||||
],
|
],
|
||||||
|
|
||||||
"el": [
|
"el": [
|
||||||
|
"editEntryLocationDialogSetCustom"
|
||||||
|
],
|
||||||
|
|
||||||
|
"es": [
|
||||||
|
"widgetOpenPageHome",
|
||||||
"widgetOpenPageCollection",
|
"widgetOpenPageCollection",
|
||||||
"durationDialogSeconds"
|
"widgetOpenPageViewer",
|
||||||
|
"editEntryLocationDialogSetCustom"
|
||||||
],
|
],
|
||||||
|
|
||||||
"fa": [
|
"fa": [
|
||||||
|
@ -212,11 +217,11 @@
|
||||||
"exportEntryDialogWidth",
|
"exportEntryDialogWidth",
|
||||||
"exportEntryDialogHeight",
|
"exportEntryDialogHeight",
|
||||||
"renameEntryDialogLabel",
|
"renameEntryDialogLabel",
|
||||||
|
"editEntryDialogCopyFromItem",
|
||||||
"editEntryDialogTargetFieldsHeader",
|
"editEntryDialogTargetFieldsHeader",
|
||||||
"editEntryDateDialogTitle",
|
"editEntryDateDialogTitle",
|
||||||
"editEntryDateDialogSetCustom",
|
"editEntryDateDialogSetCustom",
|
||||||
"editEntryDateDialogCopyField",
|
"editEntryDateDialogCopyField",
|
||||||
"editEntryDialogCopyFromItem",
|
|
||||||
"editEntryDateDialogExtractFromTitle",
|
"editEntryDateDialogExtractFromTitle",
|
||||||
"editEntryDateDialogShift",
|
"editEntryDateDialogShift",
|
||||||
"editEntryDateDialogSourceFileModifiedDate",
|
"editEntryDateDialogSourceFileModifiedDate",
|
||||||
|
@ -224,7 +229,457 @@
|
||||||
"durationDialogMinutes",
|
"durationDialogMinutes",
|
||||||
"durationDialogSeconds",
|
"durationDialogSeconds",
|
||||||
"editEntryLocationDialogTitle",
|
"editEntryLocationDialogTitle",
|
||||||
"editEntryLocationDialogChooseOnMapTooltip",
|
"editEntryLocationDialogSetCustom",
|
||||||
|
"editEntryLocationDialogChooseOnMap",
|
||||||
|
"editEntryLocationDialogLatitude",
|
||||||
|
"editEntryLocationDialogLongitude",
|
||||||
|
"locationPickerUseThisLocationButton",
|
||||||
|
"editEntryRatingDialogTitle",
|
||||||
|
"removeEntryMetadataDialogTitle",
|
||||||
|
"removeEntryMetadataDialogMore",
|
||||||
|
"removeEntryMetadataMotionPhotoXmpWarningDialogMessage",
|
||||||
|
"convertMotionPhotoToStillImageWarningDialogMessage",
|
||||||
|
"videoSpeedDialogLabel",
|
||||||
|
"videoStreamSelectionDialogVideo",
|
||||||
|
"videoStreamSelectionDialogAudio",
|
||||||
|
"videoStreamSelectionDialogText",
|
||||||
|
"videoStreamSelectionDialogOff",
|
||||||
|
"videoStreamSelectionDialogTrack",
|
||||||
|
"videoStreamSelectionDialogNoSelection",
|
||||||
|
"genericSuccessFeedback",
|
||||||
|
"genericFailureFeedback",
|
||||||
|
"menuActionConfigureView",
|
||||||
|
"menuActionSelect",
|
||||||
|
"menuActionSelectAll",
|
||||||
|
"menuActionSelectNone",
|
||||||
|
"menuActionMap",
|
||||||
|
"menuActionSlideshow",
|
||||||
|
"menuActionStats",
|
||||||
|
"viewDialogSortSectionTitle",
|
||||||
|
"viewDialogGroupSectionTitle",
|
||||||
|
"viewDialogLayoutSectionTitle",
|
||||||
|
"viewDialogReverseSortOrder",
|
||||||
|
"tileLayoutMosaic",
|
||||||
|
"tileLayoutGrid",
|
||||||
|
"tileLayoutList",
|
||||||
|
"coverDialogTabCover",
|
||||||
|
"coverDialogTabApp",
|
||||||
|
"coverDialogTabColor",
|
||||||
|
"appPickDialogTitle",
|
||||||
|
"appPickDialogNone",
|
||||||
|
"aboutPageTitle",
|
||||||
|
"aboutLinkLicense",
|
||||||
|
"aboutLinkPolicy",
|
||||||
|
"aboutBugSectionTitle",
|
||||||
|
"aboutBugSaveLogInstruction",
|
||||||
|
"aboutBugCopyInfoInstruction",
|
||||||
|
"aboutBugCopyInfoButton",
|
||||||
|
"aboutBugReportInstruction",
|
||||||
|
"aboutBugReportButton",
|
||||||
|
"aboutCreditsSectionTitle",
|
||||||
|
"aboutCreditsWorldAtlas1",
|
||||||
|
"aboutCreditsWorldAtlas2",
|
||||||
|
"aboutTranslatorsSectionTitle",
|
||||||
|
"aboutLicensesSectionTitle",
|
||||||
|
"aboutLicensesBanner",
|
||||||
|
"aboutLicensesAndroidLibrariesSectionTitle",
|
||||||
|
"aboutLicensesFlutterPluginsSectionTitle",
|
||||||
|
"aboutLicensesFlutterPackagesSectionTitle",
|
||||||
|
"aboutLicensesDartPackagesSectionTitle",
|
||||||
|
"aboutLicensesShowAllButtonLabel",
|
||||||
|
"policyPageTitle",
|
||||||
|
"collectionPageTitle",
|
||||||
|
"collectionPickPageTitle",
|
||||||
|
"collectionSelectPageTitle",
|
||||||
|
"collectionActionShowTitleSearch",
|
||||||
|
"collectionActionHideTitleSearch",
|
||||||
|
"collectionActionAddShortcut",
|
||||||
|
"collectionActionEmptyBin",
|
||||||
|
"collectionActionCopy",
|
||||||
|
"collectionActionMove",
|
||||||
|
"collectionActionRescan",
|
||||||
|
"collectionActionEdit",
|
||||||
|
"collectionSearchTitlesHintText",
|
||||||
|
"collectionGroupAlbum",
|
||||||
|
"collectionGroupMonth",
|
||||||
|
"collectionGroupDay",
|
||||||
|
"collectionGroupNone",
|
||||||
|
"sectionUnknown",
|
||||||
|
"dateToday",
|
||||||
|
"dateYesterday",
|
||||||
|
"dateThisMonth",
|
||||||
|
"collectionDeleteFailureFeedback",
|
||||||
|
"collectionCopyFailureFeedback",
|
||||||
|
"collectionMoveFailureFeedback",
|
||||||
|
"collectionRenameFailureFeedback",
|
||||||
|
"collectionEditFailureFeedback",
|
||||||
|
"collectionExportFailureFeedback",
|
||||||
|
"collectionCopySuccessFeedback",
|
||||||
|
"collectionMoveSuccessFeedback",
|
||||||
|
"collectionRenameSuccessFeedback",
|
||||||
|
"collectionEditSuccessFeedback",
|
||||||
|
"collectionEmptyFavourites",
|
||||||
|
"collectionEmptyVideos",
|
||||||
|
"collectionEmptyImages",
|
||||||
|
"collectionEmptyGrantAccessButtonLabel",
|
||||||
|
"collectionSelectSectionTooltip",
|
||||||
|
"collectionDeselectSectionTooltip",
|
||||||
|
"drawerAboutButton",
|
||||||
|
"drawerSettingsButton",
|
||||||
|
"drawerCollectionAll",
|
||||||
|
"drawerCollectionFavourites",
|
||||||
|
"drawerCollectionImages",
|
||||||
|
"drawerCollectionVideos",
|
||||||
|
"drawerCollectionAnimated",
|
||||||
|
"drawerCollectionMotionPhotos",
|
||||||
|
"drawerCollectionPanoramas",
|
||||||
|
"drawerCollectionRaws",
|
||||||
|
"drawerCollectionSphericalVideos",
|
||||||
|
"drawerAlbumPage",
|
||||||
|
"drawerCountryPage",
|
||||||
|
"drawerTagPage",
|
||||||
|
"sortByDate",
|
||||||
|
"sortByName",
|
||||||
|
"sortByItemCount",
|
||||||
|
"sortBySize",
|
||||||
|
"sortByAlbumFileName",
|
||||||
|
"sortByRating",
|
||||||
|
"sortOrderNewestFirst",
|
||||||
|
"sortOrderOldestFirst",
|
||||||
|
"sortOrderAtoZ",
|
||||||
|
"sortOrderZtoA",
|
||||||
|
"sortOrderHighestFirst",
|
||||||
|
"sortOrderLowestFirst",
|
||||||
|
"sortOrderLargestFirst",
|
||||||
|
"sortOrderSmallestFirst",
|
||||||
|
"albumGroupTier",
|
||||||
|
"albumGroupType",
|
||||||
|
"albumGroupVolume",
|
||||||
|
"albumGroupNone",
|
||||||
|
"albumMimeTypeMixed",
|
||||||
|
"albumPickPageTitleCopy",
|
||||||
|
"albumPickPageTitleExport",
|
||||||
|
"albumPickPageTitleMove",
|
||||||
|
"albumPickPageTitlePick",
|
||||||
|
"albumCamera",
|
||||||
|
"albumDownload",
|
||||||
|
"albumScreenshots",
|
||||||
|
"albumScreenRecordings",
|
||||||
|
"albumVideoCaptures",
|
||||||
|
"albumPageTitle",
|
||||||
|
"albumEmpty",
|
||||||
|
"createAlbumTooltip",
|
||||||
|
"createAlbumButtonLabel",
|
||||||
|
"newFilterBanner",
|
||||||
|
"countryPageTitle",
|
||||||
|
"countryEmpty",
|
||||||
|
"tagPageTitle",
|
||||||
|
"tagEmpty",
|
||||||
|
"binPageTitle",
|
||||||
|
"searchCollectionFieldHint",
|
||||||
|
"searchRecentSectionTitle",
|
||||||
|
"searchDateSectionTitle",
|
||||||
|
"searchAlbumsSectionTitle",
|
||||||
|
"searchCountriesSectionTitle",
|
||||||
|
"searchPlacesSectionTitle",
|
||||||
|
"searchTagsSectionTitle",
|
||||||
|
"searchRatingSectionTitle",
|
||||||
|
"searchMetadataSectionTitle",
|
||||||
|
"settingsPageTitle",
|
||||||
|
"settingsSystemDefault",
|
||||||
|
"settingsDefault",
|
||||||
|
"settingsDisabled",
|
||||||
|
"settingsSearchFieldLabel",
|
||||||
|
"settingsSearchEmpty",
|
||||||
|
"settingsActionExport",
|
||||||
|
"settingsActionExportDialogTitle",
|
||||||
|
"settingsActionImport",
|
||||||
|
"settingsActionImportDialogTitle",
|
||||||
|
"appExportCovers",
|
||||||
|
"appExportFavourites",
|
||||||
|
"appExportSettings",
|
||||||
|
"settingsNavigationSectionTitle",
|
||||||
|
"settingsHomeTile",
|
||||||
|
"settingsHomeDialogTitle",
|
||||||
|
"settingsShowBottomNavigationBar",
|
||||||
|
"settingsKeepScreenOnTile",
|
||||||
|
"settingsKeepScreenOnDialogTitle",
|
||||||
|
"settingsDoubleBackExit",
|
||||||
|
"settingsConfirmationTile",
|
||||||
|
"settingsConfirmationDialogTitle",
|
||||||
|
"settingsConfirmationBeforeDeleteItems",
|
||||||
|
"settingsConfirmationBeforeMoveToBinItems",
|
||||||
|
"settingsConfirmationBeforeMoveUndatedItems",
|
||||||
|
"settingsConfirmationAfterMoveToBinItems",
|
||||||
|
"settingsNavigationDrawerTile",
|
||||||
|
"settingsNavigationDrawerEditorPageTitle",
|
||||||
|
"settingsNavigationDrawerBanner",
|
||||||
|
"settingsNavigationDrawerTabTypes",
|
||||||
|
"settingsNavigationDrawerTabAlbums",
|
||||||
|
"settingsNavigationDrawerTabPages",
|
||||||
|
"settingsNavigationDrawerAddAlbum",
|
||||||
|
"settingsThumbnailSectionTitle",
|
||||||
|
"settingsThumbnailOverlayTile",
|
||||||
|
"settingsThumbnailOverlayPageTitle",
|
||||||
|
"settingsThumbnailShowFavouriteIcon",
|
||||||
|
"settingsThumbnailShowTagIcon",
|
||||||
|
"settingsThumbnailShowLocationIcon",
|
||||||
|
"settingsThumbnailShowMotionPhotoIcon",
|
||||||
|
"settingsThumbnailShowRating",
|
||||||
|
"settingsThumbnailShowRawIcon",
|
||||||
|
"settingsThumbnailShowVideoDuration",
|
||||||
|
"settingsCollectionQuickActionsTile",
|
||||||
|
"settingsCollectionQuickActionEditorPageTitle",
|
||||||
|
"settingsCollectionQuickActionTabBrowsing",
|
||||||
|
"settingsCollectionQuickActionTabSelecting",
|
||||||
|
"settingsCollectionBrowsingQuickActionEditorBanner",
|
||||||
|
"settingsCollectionSelectionQuickActionEditorBanner",
|
||||||
|
"settingsViewerSectionTitle",
|
||||||
|
"settingsViewerGestureSideTapNext",
|
||||||
|
"settingsViewerUseCutout",
|
||||||
|
"settingsViewerMaximumBrightness",
|
||||||
|
"settingsMotionPhotoAutoPlay",
|
||||||
|
"settingsImageBackground",
|
||||||
|
"settingsViewerQuickActionsTile",
|
||||||
|
"settingsViewerQuickActionEditorPageTitle",
|
||||||
|
"settingsViewerQuickActionEditorBanner",
|
||||||
|
"settingsViewerQuickActionEditorDisplayedButtonsSectionTitle",
|
||||||
|
"settingsViewerQuickActionEditorAvailableButtonsSectionTitle",
|
||||||
|
"settingsViewerQuickActionEmpty",
|
||||||
|
"settingsViewerOverlayTile",
|
||||||
|
"settingsViewerOverlayPageTitle",
|
||||||
|
"settingsViewerShowOverlayOnOpening",
|
||||||
|
"settingsViewerShowMinimap",
|
||||||
|
"settingsViewerShowInformation",
|
||||||
|
"settingsViewerShowInformationSubtitle",
|
||||||
|
"settingsViewerShowShootingDetails",
|
||||||
|
"settingsViewerShowOverlayThumbnails",
|
||||||
|
"settingsViewerEnableOverlayBlurEffect",
|
||||||
|
"settingsViewerSlideshowTile",
|
||||||
|
"settingsViewerSlideshowPageTitle",
|
||||||
|
"settingsSlideshowRepeat",
|
||||||
|
"settingsSlideshowShuffle",
|
||||||
|
"settingsSlideshowFillScreen",
|
||||||
|
"settingsSlideshowAnimatedZoomEffect",
|
||||||
|
"settingsSlideshowTransitionTile",
|
||||||
|
"settingsSlideshowIntervalTile",
|
||||||
|
"settingsSlideshowVideoPlaybackTile",
|
||||||
|
"settingsSlideshowVideoPlaybackDialogTitle",
|
||||||
|
"settingsVideoPageTitle",
|
||||||
|
"settingsVideoSectionTitle",
|
||||||
|
"settingsVideoShowVideos",
|
||||||
|
"settingsVideoEnableHardwareAcceleration",
|
||||||
|
"settingsVideoAutoPlay",
|
||||||
|
"settingsVideoLoopModeTile",
|
||||||
|
"settingsVideoLoopModeDialogTitle",
|
||||||
|
"settingsSubtitleThemeTile",
|
||||||
|
"settingsSubtitleThemePageTitle",
|
||||||
|
"settingsSubtitleThemeSample",
|
||||||
|
"settingsSubtitleThemeTextAlignmentTile",
|
||||||
|
"settingsSubtitleThemeTextAlignmentDialogTitle",
|
||||||
|
"settingsSubtitleThemeTextSize",
|
||||||
|
"settingsSubtitleThemeShowOutline",
|
||||||
|
"settingsSubtitleThemeTextColor",
|
||||||
|
"settingsSubtitleThemeTextOpacity",
|
||||||
|
"settingsSubtitleThemeBackgroundColor",
|
||||||
|
"settingsSubtitleThemeBackgroundOpacity",
|
||||||
|
"settingsSubtitleThemeTextAlignmentLeft",
|
||||||
|
"settingsSubtitleThemeTextAlignmentCenter",
|
||||||
|
"settingsSubtitleThemeTextAlignmentRight",
|
||||||
|
"settingsVideoControlsTile",
|
||||||
|
"settingsVideoControlsPageTitle",
|
||||||
|
"settingsVideoButtonsTile",
|
||||||
|
"settingsVideoGestureDoubleTapTogglePlay",
|
||||||
|
"settingsVideoGestureSideDoubleTapSeek",
|
||||||
|
"settingsPrivacySectionTitle",
|
||||||
|
"settingsAllowInstalledAppAccess",
|
||||||
|
"settingsAllowInstalledAppAccessSubtitle",
|
||||||
|
"settingsAllowErrorReporting",
|
||||||
|
"settingsSaveSearchHistory",
|
||||||
|
"settingsEnableBin",
|
||||||
|
"settingsEnableBinSubtitle",
|
||||||
|
"settingsHiddenItemsTile",
|
||||||
|
"settingsHiddenItemsPageTitle",
|
||||||
|
"settingsHiddenItemsTabFilters",
|
||||||
|
"settingsHiddenFiltersBanner",
|
||||||
|
"settingsHiddenFiltersEmpty",
|
||||||
|
"settingsHiddenItemsTabPaths",
|
||||||
|
"settingsHiddenPathsBanner",
|
||||||
|
"addPathTooltip",
|
||||||
|
"settingsStorageAccessTile",
|
||||||
|
"settingsStorageAccessPageTitle",
|
||||||
|
"settingsStorageAccessBanner",
|
||||||
|
"settingsStorageAccessEmpty",
|
||||||
|
"settingsStorageAccessRevokeTooltip",
|
||||||
|
"settingsAccessibilitySectionTitle",
|
||||||
|
"settingsRemoveAnimationsTile",
|
||||||
|
"settingsRemoveAnimationsDialogTitle",
|
||||||
|
"settingsTimeToTakeActionTile",
|
||||||
|
"settingsDisplaySectionTitle",
|
||||||
|
"settingsThemeBrightnessTile",
|
||||||
|
"settingsThemeBrightnessDialogTitle",
|
||||||
|
"settingsThemeColorHighlights",
|
||||||
|
"settingsThemeEnableDynamicColor",
|
||||||
|
"settingsDisplayRefreshRateModeTile",
|
||||||
|
"settingsDisplayRefreshRateModeDialogTitle",
|
||||||
|
"settingsLanguageSectionTitle",
|
||||||
|
"settingsLanguageTile",
|
||||||
|
"settingsLanguagePageTitle",
|
||||||
|
"settingsCoordinateFormatTile",
|
||||||
|
"settingsCoordinateFormatDialogTitle",
|
||||||
|
"settingsUnitSystemTile",
|
||||||
|
"settingsUnitSystemDialogTitle",
|
||||||
|
"settingsScreenSaverPageTitle",
|
||||||
|
"settingsWidgetPageTitle",
|
||||||
|
"settingsWidgetShowOutline",
|
||||||
|
"settingsWidgetOpenPage",
|
||||||
|
"settingsCollectionTile",
|
||||||
|
"statsPageTitle",
|
||||||
|
"statsWithGps",
|
||||||
|
"statsTopCountriesSectionTitle",
|
||||||
|
"statsTopPlacesSectionTitle",
|
||||||
|
"statsTopTagsSectionTitle",
|
||||||
|
"statsTopAlbumsSectionTitle",
|
||||||
|
"viewerOpenPanoramaButtonLabel",
|
||||||
|
"viewerSetWallpaperButtonLabel",
|
||||||
|
"viewerErrorUnknown",
|
||||||
|
"viewerErrorDoesNotExist",
|
||||||
|
"viewerInfoPageTitle",
|
||||||
|
"viewerInfoBackToViewerTooltip",
|
||||||
|
"viewerInfoUnknown",
|
||||||
|
"viewerInfoLabelDescription",
|
||||||
|
"viewerInfoLabelTitle",
|
||||||
|
"viewerInfoLabelDate",
|
||||||
|
"viewerInfoLabelResolution",
|
||||||
|
"viewerInfoLabelSize",
|
||||||
|
"viewerInfoLabelUri",
|
||||||
|
"viewerInfoLabelPath",
|
||||||
|
"viewerInfoLabelDuration",
|
||||||
|
"viewerInfoLabelOwner",
|
||||||
|
"viewerInfoLabelCoordinates",
|
||||||
|
"viewerInfoLabelAddress",
|
||||||
|
"mapStyleDialogTitle",
|
||||||
|
"mapStyleTooltip",
|
||||||
|
"mapZoomInTooltip",
|
||||||
|
"mapZoomOutTooltip",
|
||||||
|
"mapPointNorthUpTooltip",
|
||||||
|
"mapAttributionOsmHot",
|
||||||
|
"mapAttributionStamen",
|
||||||
|
"openMapPageTooltip",
|
||||||
|
"mapEmptyRegion",
|
||||||
|
"viewerInfoOpenEmbeddedFailureFeedback",
|
||||||
|
"viewerInfoOpenLinkText",
|
||||||
|
"viewerInfoViewXmlLinkText",
|
||||||
|
"viewerInfoSearchFieldLabel",
|
||||||
|
"viewerInfoSearchEmpty",
|
||||||
|
"viewerInfoSearchSuggestionDate",
|
||||||
|
"viewerInfoSearchSuggestionDescription",
|
||||||
|
"viewerInfoSearchSuggestionDimensions",
|
||||||
|
"viewerInfoSearchSuggestionResolution",
|
||||||
|
"viewerInfoSearchSuggestionRights",
|
||||||
|
"wallpaperUseScrollEffect",
|
||||||
|
"tagEditorPageTitle",
|
||||||
|
"tagEditorPageNewTagFieldLabel",
|
||||||
|
"tagEditorPageAddTagTooltip",
|
||||||
|
"tagEditorSectionRecent",
|
||||||
|
"panoramaEnableSensorControl",
|
||||||
|
"panoramaDisableSensorControl",
|
||||||
|
"sourceViewerPageTitle",
|
||||||
|
"filePickerShowHiddenFiles",
|
||||||
|
"filePickerDoNotShowHiddenFiles",
|
||||||
|
"filePickerOpenFrom",
|
||||||
|
"filePickerNoItems",
|
||||||
|
"filePickerUseThisFolder"
|
||||||
|
],
|
||||||
|
|
||||||
|
"fr": [
|
||||||
|
"editEntryLocationDialogSetCustom"
|
||||||
|
],
|
||||||
|
|
||||||
|
"gl": [
|
||||||
|
"accessibilityAnimationsRemove",
|
||||||
|
"accessibilityAnimationsKeep",
|
||||||
|
"displayRefreshRatePreferHighest",
|
||||||
|
"displayRefreshRatePreferLowest",
|
||||||
|
"videoPlaybackSkip",
|
||||||
|
"videoPlaybackMuted",
|
||||||
|
"videoPlaybackWithSound",
|
||||||
|
"themeBrightnessLight",
|
||||||
|
"themeBrightnessDark",
|
||||||
|
"themeBrightnessBlack",
|
||||||
|
"viewerTransitionSlide",
|
||||||
|
"viewerTransitionParallax",
|
||||||
|
"viewerTransitionFade",
|
||||||
|
"viewerTransitionZoomIn",
|
||||||
|
"viewerTransitionNone",
|
||||||
|
"wallpaperTargetHome",
|
||||||
|
"wallpaperTargetLock",
|
||||||
|
"wallpaperTargetHomeLock",
|
||||||
|
"widgetOpenPageHome",
|
||||||
|
"widgetOpenPageCollection",
|
||||||
|
"widgetOpenPageViewer",
|
||||||
|
"albumTierNew",
|
||||||
|
"albumTierPinned",
|
||||||
|
"albumTierSpecial",
|
||||||
|
"albumTierApps",
|
||||||
|
"albumTierRegular",
|
||||||
|
"storageVolumeDescriptionFallbackPrimary",
|
||||||
|
"storageVolumeDescriptionFallbackNonPrimary",
|
||||||
|
"rootDirectoryDescription",
|
||||||
|
"otherDirectoryDescription",
|
||||||
|
"storageAccessDialogMessage",
|
||||||
|
"restrictedAccessDialogMessage",
|
||||||
|
"notEnoughSpaceDialogMessage",
|
||||||
|
"missingSystemFilePickerDialogMessage",
|
||||||
|
"unsupportedTypeDialogMessage",
|
||||||
|
"nameConflictDialogSingleSourceMessage",
|
||||||
|
"nameConflictDialogMultipleSourceMessage",
|
||||||
|
"addShortcutDialogLabel",
|
||||||
|
"addShortcutButtonLabel",
|
||||||
|
"noMatchingAppDialogMessage",
|
||||||
|
"binEntriesConfirmationDialogMessage",
|
||||||
|
"deleteEntriesConfirmationDialogMessage",
|
||||||
|
"moveUndatedConfirmationDialogMessage",
|
||||||
|
"moveUndatedConfirmationDialogSetDate",
|
||||||
|
"videoResumeDialogMessage",
|
||||||
|
"videoStartOverButtonLabel",
|
||||||
|
"videoResumeButtonLabel",
|
||||||
|
"setCoverDialogLatest",
|
||||||
|
"setCoverDialogAuto",
|
||||||
|
"setCoverDialogCustom",
|
||||||
|
"hideFilterConfirmationDialogMessage",
|
||||||
|
"newAlbumDialogTitle",
|
||||||
|
"newAlbumDialogNameLabel",
|
||||||
|
"newAlbumDialogNameLabelAlreadyExistsHelper",
|
||||||
|
"newAlbumDialogStorageLabel",
|
||||||
|
"renameAlbumDialogLabel",
|
||||||
|
"renameAlbumDialogLabelAlreadyExistsHelper",
|
||||||
|
"renameEntrySetPageTitle",
|
||||||
|
"renameEntrySetPagePatternFieldLabel",
|
||||||
|
"renameEntrySetPageInsertTooltip",
|
||||||
|
"renameEntrySetPagePreviewSectionTitle",
|
||||||
|
"renameProcessorCounter",
|
||||||
|
"renameProcessorName",
|
||||||
|
"deleteSingleAlbumConfirmationDialogMessage",
|
||||||
|
"deleteMultiAlbumConfirmationDialogMessage",
|
||||||
|
"exportEntryDialogFormat",
|
||||||
|
"exportEntryDialogWidth",
|
||||||
|
"exportEntryDialogHeight",
|
||||||
|
"renameEntryDialogLabel",
|
||||||
|
"editEntryDialogCopyFromItem",
|
||||||
|
"editEntryDialogTargetFieldsHeader",
|
||||||
|
"editEntryDateDialogTitle",
|
||||||
|
"editEntryDateDialogSetCustom",
|
||||||
|
"editEntryDateDialogCopyField",
|
||||||
|
"editEntryDateDialogExtractFromTitle",
|
||||||
|
"editEntryDateDialogShift",
|
||||||
|
"editEntryDateDialogSourceFileModifiedDate",
|
||||||
|
"durationDialogHours",
|
||||||
|
"durationDialogMinutes",
|
||||||
|
"durationDialogSeconds",
|
||||||
|
"editEntryLocationDialogTitle",
|
||||||
|
"editEntryLocationDialogSetCustom",
|
||||||
|
"editEntryLocationDialogChooseOnMap",
|
||||||
"editEntryLocationDialogLatitude",
|
"editEntryLocationDialogLatitude",
|
||||||
"editEntryLocationDialogLongitude",
|
"editEntryLocationDialogLongitude",
|
||||||
"locationPickerUseThisLocationButton",
|
"locationPickerUseThisLocationButton",
|
||||||
|
@ -594,6 +1049,7 @@
|
||||||
"widgetOpenPageCollection",
|
"widgetOpenPageCollection",
|
||||||
"widgetOpenPageViewer",
|
"widgetOpenPageViewer",
|
||||||
"durationDialogSeconds",
|
"durationDialogSeconds",
|
||||||
|
"editEntryLocationDialogSetCustom",
|
||||||
"tileLayoutMosaic",
|
"tileLayoutMosaic",
|
||||||
"albumGroupType",
|
"albumGroupType",
|
||||||
"albumMimeTypeMixed",
|
"albumMimeTypeMixed",
|
||||||
|
@ -605,8 +1061,7 @@
|
||||||
],
|
],
|
||||||
|
|
||||||
"it": [
|
"it": [
|
||||||
"widgetOpenPageCollection",
|
"editEntryLocationDialogSetCustom"
|
||||||
"durationDialogSeconds"
|
|
||||||
],
|
],
|
||||||
|
|
||||||
"ja": [
|
"ja": [
|
||||||
|
@ -621,6 +1076,7 @@
|
||||||
"widgetOpenPageCollection",
|
"widgetOpenPageCollection",
|
||||||
"widgetOpenPageViewer",
|
"widgetOpenPageViewer",
|
||||||
"durationDialogSeconds",
|
"durationDialogSeconds",
|
||||||
|
"editEntryLocationDialogSetCustom",
|
||||||
"viewDialogReverseSortOrder",
|
"viewDialogReverseSortOrder",
|
||||||
"tileLayoutMosaic",
|
"tileLayoutMosaic",
|
||||||
"sortOrderNewestFirst",
|
"sortOrderNewestFirst",
|
||||||
|
@ -644,6 +1100,10 @@
|
||||||
"wallpaperUseScrollEffect"
|
"wallpaperUseScrollEffect"
|
||||||
],
|
],
|
||||||
|
|
||||||
|
"ko": [
|
||||||
|
"editEntryLocationDialogSetCustom"
|
||||||
|
],
|
||||||
|
|
||||||
"nb": [
|
"nb": [
|
||||||
"videoActionCaptureFrame",
|
"videoActionCaptureFrame",
|
||||||
"videoActionSelectStreams",
|
"videoActionSelectStreams",
|
||||||
|
@ -672,6 +1132,7 @@
|
||||||
"editEntryDateDialogShift",
|
"editEntryDateDialogShift",
|
||||||
"editEntryDateDialogSourceFileModifiedDate",
|
"editEntryDateDialogSourceFileModifiedDate",
|
||||||
"editEntryLocationDialogTitle",
|
"editEntryLocationDialogTitle",
|
||||||
|
"editEntryLocationDialogSetCustom",
|
||||||
"locationPickerUseThisLocationButton",
|
"locationPickerUseThisLocationButton",
|
||||||
"removeEntryMetadataMotionPhotoXmpWarningDialogMessage",
|
"removeEntryMetadataMotionPhotoXmpWarningDialogMessage",
|
||||||
"videoStreamSelectionDialogText",
|
"videoStreamSelectionDialogText",
|
||||||
|
@ -756,6 +1217,7 @@
|
||||||
"widgetOpenPageCollection",
|
"widgetOpenPageCollection",
|
||||||
"widgetOpenPageViewer",
|
"widgetOpenPageViewer",
|
||||||
"durationDialogSeconds",
|
"durationDialogSeconds",
|
||||||
|
"editEntryLocationDialogSetCustom",
|
||||||
"aboutLinkPolicy",
|
"aboutLinkPolicy",
|
||||||
"policyPageTitle"
|
"policyPageTitle"
|
||||||
],
|
],
|
||||||
|
@ -870,11 +1332,11 @@
|
||||||
"exportEntryDialogWidth",
|
"exportEntryDialogWidth",
|
||||||
"exportEntryDialogHeight",
|
"exportEntryDialogHeight",
|
||||||
"renameEntryDialogLabel",
|
"renameEntryDialogLabel",
|
||||||
|
"editEntryDialogCopyFromItem",
|
||||||
"editEntryDialogTargetFieldsHeader",
|
"editEntryDialogTargetFieldsHeader",
|
||||||
"editEntryDateDialogTitle",
|
"editEntryDateDialogTitle",
|
||||||
"editEntryDateDialogSetCustom",
|
"editEntryDateDialogSetCustom",
|
||||||
"editEntryDateDialogCopyField",
|
"editEntryDateDialogCopyField",
|
||||||
"editEntryDialogCopyFromItem",
|
|
||||||
"editEntryDateDialogExtractFromTitle",
|
"editEntryDateDialogExtractFromTitle",
|
||||||
"editEntryDateDialogShift",
|
"editEntryDateDialogShift",
|
||||||
"editEntryDateDialogSourceFileModifiedDate",
|
"editEntryDateDialogSourceFileModifiedDate",
|
||||||
|
@ -882,7 +1344,8 @@
|
||||||
"durationDialogMinutes",
|
"durationDialogMinutes",
|
||||||
"durationDialogSeconds",
|
"durationDialogSeconds",
|
||||||
"editEntryLocationDialogTitle",
|
"editEntryLocationDialogTitle",
|
||||||
"editEntryLocationDialogChooseOnMapTooltip",
|
"editEntryLocationDialogSetCustom",
|
||||||
|
"editEntryLocationDialogChooseOnMap",
|
||||||
"editEntryLocationDialogLatitude",
|
"editEntryLocationDialogLatitude",
|
||||||
"editEntryLocationDialogLongitude",
|
"editEntryLocationDialogLongitude",
|
||||||
"locationPickerUseThisLocationButton",
|
"locationPickerUseThisLocationButton",
|
||||||
|
@ -1245,7 +1708,11 @@
|
||||||
],
|
],
|
||||||
|
|
||||||
"pt": [
|
"pt": [
|
||||||
"durationDialogSeconds"
|
"editEntryLocationDialogSetCustom"
|
||||||
|
],
|
||||||
|
|
||||||
|
"ru": [
|
||||||
|
"editEntryLocationDialogSetCustom"
|
||||||
],
|
],
|
||||||
|
|
||||||
"tr": [
|
"tr": [
|
||||||
|
@ -1273,6 +1740,7 @@
|
||||||
"widgetOpenPageCollection",
|
"widgetOpenPageCollection",
|
||||||
"widgetOpenPageViewer",
|
"widgetOpenPageViewer",
|
||||||
"durationDialogSeconds",
|
"durationDialogSeconds",
|
||||||
|
"editEntryLocationDialogSetCustom",
|
||||||
"menuActionSlideshow",
|
"menuActionSlideshow",
|
||||||
"viewDialogReverseSortOrder",
|
"viewDialogReverseSortOrder",
|
||||||
"tileLayoutMosaic",
|
"tileLayoutMosaic",
|
||||||
|
@ -1310,7 +1778,6 @@
|
||||||
],
|
],
|
||||||
|
|
||||||
"zh": [
|
"zh": [
|
||||||
"widgetOpenPageCollection",
|
"editEntryLocationDialogSetCustom"
|
||||||
"durationDialogSeconds"
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue