#990 renaming: processor for hash (md5/sha1/sha256)
This commit is contained in:
parent
949f9a514f
commit
65e224ef57
12 changed files with 204 additions and 41 deletions
|
@ -7,6 +7,7 @@ All notable changes to this project will be documented in this file.
|
|||
### Added
|
||||
|
||||
- Cataloguing: identify Apple variant of HDR images
|
||||
- Collection: allow using hash (md5/sha1/sha256) when bulk renaming
|
||||
- option to force using western arabic numerals for dates
|
||||
|
||||
### Changed
|
||||
|
|
|
@ -85,6 +85,7 @@ import deckers.thibault.aves.metadata.xmp.XMP.isMotionPhoto
|
|||
import deckers.thibault.aves.metadata.xmp.XMP.isPanorama
|
||||
import deckers.thibault.aves.model.FieldMap
|
||||
import deckers.thibault.aves.utils.ContextUtils.queryContentPropValue
|
||||
import deckers.thibault.aves.utils.HashUtils
|
||||
import deckers.thibault.aves.utils.LogUtils
|
||||
import deckers.thibault.aves.utils.MimeTypes
|
||||
import deckers.thibault.aves.utils.MimeTypes.TIFF_EXTENSION_PATTERN
|
||||
|
@ -104,6 +105,7 @@ import org.json.JSONObject
|
|||
import java.nio.charset.StandardCharsets
|
||||
import java.text.DecimalFormat
|
||||
import java.text.ParseException
|
||||
import java.util.Locale
|
||||
import kotlin.math.roundToInt
|
||||
import kotlin.math.roundToLong
|
||||
|
||||
|
@ -1307,10 +1309,36 @@ class MetadataFetchHandler(private val context: Context) : MethodCallHandler {
|
|||
return
|
||||
}
|
||||
|
||||
val metadataMap = HashMap<String, Any>()
|
||||
val metadataMap = HashMap<String, Any?>()
|
||||
|
||||
val hashFields = fields.filter { it.startsWith(HASH_FIELD_PREFIX) }.toSet()
|
||||
metadataMap.putAll(getHashFields(uri, mimeType, sizeBytes, hashFields))
|
||||
|
||||
val exifFields = fields.filterNot { hashFields.contains(it) }.toSet()
|
||||
metadataMap.putAll(getExifFields(uri, mimeType, sizeBytes, exifFields))
|
||||
|
||||
result.success(metadataMap)
|
||||
}
|
||||
|
||||
private fun getHashFields(uri: Uri, mimeType: String, sizeBytes: Long?, fields: Set<String>): FieldMap {
|
||||
val metadataMap = HashMap<String, Any?>()
|
||||
fields.forEach { field ->
|
||||
val function = field.substringAfter(HASH_FIELD_PREFIX).lowercase(Locale.ROOT)
|
||||
try {
|
||||
Metadata.openSafeInputStream(context, uri, mimeType, sizeBytes)?.use { input ->
|
||||
metadataMap[field] = HashUtils.getHash(input, function)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.w(LOG_TAG, "failed to get hash for mimeType=$mimeType uri=$uri function=$function", e)
|
||||
}
|
||||
}
|
||||
return metadataMap
|
||||
}
|
||||
|
||||
private fun getExifFields(uri: Uri, mimeType: String, sizeBytes: Long?, fields: Set<String>): FieldMap {
|
||||
val metadataMap = HashMap<String, Any?>()
|
||||
if (fields.isEmpty() || isVideo(mimeType)) {
|
||||
result.success(metadataMap)
|
||||
return
|
||||
return metadataMap
|
||||
}
|
||||
|
||||
var foundExif = false
|
||||
|
@ -1359,7 +1387,7 @@ class MetadataFetchHandler(private val context: Context) : MethodCallHandler {
|
|||
}
|
||||
}
|
||||
|
||||
result.success(metadataMap)
|
||||
return metadataMap
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
@ -1434,6 +1462,7 @@ class MetadataFetchHandler(private val context: Context) : MethodCallHandler {
|
|||
// additional media key
|
||||
private const val KEY_HAS_EMBEDDED_PICTURE = "Has Embedded Picture"
|
||||
|
||||
private const val HASH_FIELD_PREFIX = "hash"
|
||||
private const val VALUE_SKIPPED_DATA = "[skipped]"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
package deckers.thibault.aves.utils
|
||||
|
||||
import java.io.InputStream
|
||||
import java.math.BigInteger
|
||||
import java.security.MessageDigest
|
||||
|
||||
object HashUtils {
|
||||
fun getHash(input: InputStream, algorithmKey: String): String {
|
||||
val algorithm = toMessageDigestAlgorithm(algorithmKey)
|
||||
val digest = MessageDigest.getInstance(algorithm)
|
||||
val buffer = ByteArray(1 shl 14)
|
||||
var read: Int
|
||||
while ((input.read(buffer).also { read = it }) > 0) {
|
||||
digest.update(buffer, 0, read)
|
||||
}
|
||||
val md5sum = digest.digest()
|
||||
val output = BigInteger(1, md5sum).toString(16)
|
||||
|
||||
return when (algorithm) {
|
||||
"MD5" -> output.padStart(32, '0') // 128 bits = 32 hex digits
|
||||
"SHA-1" -> output.padStart(40, '0') // 160 bits = 40 hex digits
|
||||
"SHA-256" -> output.padStart(64, '0') // 256 bits = 64 hex digits
|
||||
else -> throw IllegalArgumentException("unsupported hash algorithm: $algorithmKey")
|
||||
}
|
||||
}
|
||||
|
||||
private fun toMessageDigestAlgorithm(algorithmKey: String): String {
|
||||
return when (algorithmKey) {
|
||||
"md5" -> "MD5"
|
||||
"sha1" -> "SHA-1"
|
||||
"sha256" -> "SHA-256"
|
||||
else -> throw IllegalArgumentException("unsupported hash algorithm: $algorithmKey")
|
||||
}
|
||||
}
|
||||
}
|
|
@ -53,23 +53,30 @@ extension ExtraMetadataFieldConvert on MetadataField {
|
|||
return MetadataType.mp4;
|
||||
case MetadataField.xmpXmpCreateDate:
|
||||
return MetadataType.xmp;
|
||||
case MetadataField.hashMd5:
|
||||
case MetadataField.hashSha1:
|
||||
case MetadataField.hashSha256:
|
||||
return MetadataType.file;
|
||||
}
|
||||
}
|
||||
|
||||
String? get toPlatform {
|
||||
if (type == MetadataType.exif) {
|
||||
return _toExifInterfaceTag();
|
||||
} else {
|
||||
switch (this) {
|
||||
case MetadataField.mp4GpsCoordinates:
|
||||
return 'gpsCoordinates';
|
||||
case MetadataField.mp4RotationDegrees:
|
||||
return 'rotationDegrees';
|
||||
case MetadataField.mp4Xmp:
|
||||
return 'xmp';
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
switch (type) {
|
||||
case MetadataType.exif:
|
||||
return _toExifInterfaceTag();
|
||||
case MetadataType.file:
|
||||
return name;
|
||||
default:
|
||||
switch (this) {
|
||||
case MetadataField.mp4GpsCoordinates:
|
||||
return 'gpsCoordinates';
|
||||
case MetadataField.mp4RotationDegrees:
|
||||
return 'rotationDegrees';
|
||||
case MetadataField.mp4Xmp:
|
||||
return 'xmp';
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -23,6 +23,8 @@ extension ExtraMetadataTypeConvert on MetadataType {
|
|||
return 'photoshop_irb';
|
||||
case MetadataType.xmp:
|
||||
return 'xmp';
|
||||
case MetadataType.file:
|
||||
return 'file';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -440,6 +440,7 @@
|
|||
"renameEntrySetPagePreviewSectionTitle": "Preview",
|
||||
|
||||
"renameProcessorCounter": "Counter",
|
||||
"renameProcessorHash": "Hash",
|
||||
"renameProcessorName": "Name",
|
||||
|
||||
"deleteSingleAlbumConfirmationDialogMessage": "{count, plural, =1{Delete this album and the item in it?} other{Delete this album and the {count} items in it?}}",
|
||||
|
|
|
@ -39,18 +39,6 @@ class NamingPattern {
|
|||
final processorKey = match.group(1);
|
||||
final processorOptions = match.group(3);
|
||||
switch (processorKey) {
|
||||
case DateNamingProcessor.key:
|
||||
if (processorOptions != null) {
|
||||
processors.add(DateNamingProcessor(processorOptions.trim(), locale));
|
||||
}
|
||||
case TagsNamingProcessor.key:
|
||||
processors.add(TagsNamingProcessor(processorOptions?.trim() ?? ''));
|
||||
case MetadataFieldNamingProcessor.key:
|
||||
if (processorOptions != null) {
|
||||
processors.add(MetadataFieldNamingProcessor(processorOptions.trim()));
|
||||
}
|
||||
case NameNamingProcessor.key:
|
||||
processors.add(const NameNamingProcessor());
|
||||
case CounterNamingProcessor.key:
|
||||
int? start, padding;
|
||||
_applyProcessorOptions(processorOptions, (key, value) {
|
||||
|
@ -65,6 +53,22 @@ class NamingPattern {
|
|||
}
|
||||
});
|
||||
processors.add(CounterNamingProcessor(start: start ?? defaultCounterStart, padding: padding ?? defaultCounterPadding));
|
||||
case DateNamingProcessor.key:
|
||||
if (processorOptions != null) {
|
||||
processors.add(DateNamingProcessor(processorOptions.trim(), locale));
|
||||
}
|
||||
case HashNamingProcessor.key:
|
||||
if (processorOptions != null) {
|
||||
processors.add(HashNamingProcessor(processorOptions.trim()));
|
||||
}
|
||||
case MetadataFieldNamingProcessor.key:
|
||||
if (processorOptions != null) {
|
||||
processors.add(MetadataFieldNamingProcessor(processorOptions.trim()));
|
||||
}
|
||||
case NameNamingProcessor.key:
|
||||
processors.add(const NameNamingProcessor());
|
||||
case TagsNamingProcessor.key:
|
||||
processors.add(TagsNamingProcessor(processorOptions?.trim() ?? ''));
|
||||
default:
|
||||
debugPrint('unsupported naming processor: ${match.group(0)}');
|
||||
}
|
||||
|
@ -106,6 +110,8 @@ class NamingPattern {
|
|||
switch (processorKey) {
|
||||
case DateNamingProcessor.key:
|
||||
return '<$processorKey, yyyyMMdd-HHmmss>';
|
||||
case HashNamingProcessor.key:
|
||||
return '<$processorKey, md5>';
|
||||
case TagsNamingProcessor.key:
|
||||
return '<$processorKey, ->';
|
||||
case CounterNamingProcessor.key:
|
||||
|
@ -204,9 +210,7 @@ class MetadataFieldNamingProcessor extends NamingProcessor {
|
|||
}
|
||||
|
||||
@override
|
||||
Set<MetadataField> getRequiredFields() {
|
||||
return {field}.whereNotNull().toSet();
|
||||
}
|
||||
Set<MetadataField> getRequiredFields() => {field}.whereNotNull().toSet();
|
||||
|
||||
@override
|
||||
String? process(AvesEntry entry, int index, Map<String, dynamic> fieldValues) {
|
||||
|
@ -247,3 +251,27 @@ class CounterNamingProcessor extends NamingProcessor {
|
|||
@override
|
||||
String? process(AvesEntry entry, int index, Map<String, dynamic> fieldValues) => '${index + start}'.padLeft(padding, '0');
|
||||
}
|
||||
|
||||
@immutable
|
||||
class HashNamingProcessor extends NamingProcessor {
|
||||
static const key = 'hash';
|
||||
static const optionFunction = 'function';
|
||||
|
||||
late final MetadataField? function;
|
||||
|
||||
@override
|
||||
List<Object?> get props => [function];
|
||||
|
||||
HashNamingProcessor(String function) {
|
||||
final lowerField = 'hash${function.toLowerCase()}';
|
||||
this.function = MetadataField.values.firstWhereOrNull((v) => v.name.toLowerCase() == lowerField);
|
||||
}
|
||||
|
||||
@override
|
||||
Set<MetadataField> getRequiredFields() => {function}.whereNotNull().toSet();
|
||||
|
||||
@override
|
||||
String? process(AvesEntry entry, int index, Map<String, dynamic> fieldValues) {
|
||||
return fieldValues[function?.toPlatform]?.toString();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@ extension ExtraMetadataTypeView on MetadataType {
|
|||
MetadataType.mp4 => 'MP4',
|
||||
MetadataType.photoshopIrb => 'Photoshop',
|
||||
MetadataType.xmp => 'XMP',
|
||||
MetadataType.file => 'File',
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -119,14 +119,19 @@ class _RenameEntrySetPageState extends State<RenameEntrySetPage> {
|
|||
icon: AIcons.more,
|
||||
title: MaterialLocalizations.of(context).moreButtonTooltip,
|
||||
items: [
|
||||
MetadataField.exifMake,
|
||||
MetadataField.exifModel,
|
||||
]
|
||||
.map((field) => PopupMenuItem(
|
||||
value: MetadataFieldNamingProcessor.keyWithField(field),
|
||||
child: MenuRow(text: field.title),
|
||||
))
|
||||
.toList(),
|
||||
...[
|
||||
MetadataField.exifMake,
|
||||
MetadataField.exifModel,
|
||||
]
|
||||
.map((field) => PopupMenuItem(
|
||||
value: MetadataFieldNamingProcessor.keyWithField(field),
|
||||
child: MenuRow(text: field.title),
|
||||
)),
|
||||
PopupMenuItem(
|
||||
value: HashNamingProcessor.key,
|
||||
child: MenuRow(text: l10n.renameProcessorHash),
|
||||
)
|
||||
],
|
||||
),
|
||||
];
|
||||
},
|
||||
|
|
|
@ -45,6 +45,8 @@ enum MetadataType {
|
|||
photoshopIrb,
|
||||
// XMP: https://en.wikipedia.org/wiki/Extensible_Metadata_Platform
|
||||
xmp,
|
||||
// others (hash, etc.)
|
||||
file,
|
||||
}
|
||||
|
||||
class MetadataTypes {
|
||||
|
|
|
@ -7,6 +7,7 @@ enum MetadataSyntheticField {
|
|||
}
|
||||
|
||||
enum MetadataField {
|
||||
// exif
|
||||
exifDate,
|
||||
exifDateOriginal,
|
||||
exifDateDigitized,
|
||||
|
@ -46,10 +47,16 @@ enum MetadataField {
|
|||
exifMake,
|
||||
exifModel,
|
||||
exifUserComment,
|
||||
// mp4
|
||||
mp4GpsCoordinates,
|
||||
mp4RotationDegrees,
|
||||
mp4Xmp,
|
||||
// xmp
|
||||
xmpXmpCreateDate,
|
||||
// file
|
||||
hashMd5,
|
||||
hashSha1,
|
||||
hashSha256,
|
||||
}
|
||||
|
||||
class MetadataFields {
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
{
|
||||
"ar": [
|
||||
"renameProcessorHash",
|
||||
"settingsForceWesternArabicNumeralsTile"
|
||||
],
|
||||
|
||||
"be": [
|
||||
"renameProcessorHash",
|
||||
"settingsForceWesternArabicNumeralsTile"
|
||||
],
|
||||
|
||||
|
@ -241,6 +243,7 @@
|
|||
"renameEntrySetPageInsertTooltip",
|
||||
"renameEntrySetPagePreviewSectionTitle",
|
||||
"renameProcessorCounter",
|
||||
"renameProcessorHash",
|
||||
"renameProcessorName",
|
||||
"deleteSingleAlbumConfirmationDialogMessage",
|
||||
"deleteMultiAlbumConfirmationDialogMessage",
|
||||
|
@ -677,6 +680,7 @@
|
|||
"videoActionABRepeat",
|
||||
"videoRepeatActionSetStart",
|
||||
"videoRepeatActionSetEnd",
|
||||
"renameProcessorHash",
|
||||
"settingsForceWesternArabicNumeralsTile"
|
||||
],
|
||||
|
||||
|
@ -793,6 +797,7 @@
|
|||
"renameEntrySetPageInsertTooltip",
|
||||
"renameEntrySetPagePreviewSectionTitle",
|
||||
"renameProcessorCounter",
|
||||
"renameProcessorHash",
|
||||
"renameProcessorName",
|
||||
"deleteSingleAlbumConfirmationDialogMessage",
|
||||
"deleteMultiAlbumConfirmationDialogMessage",
|
||||
|
@ -1229,6 +1234,7 @@
|
|||
"videoActionABRepeat",
|
||||
"videoRepeatActionSetStart",
|
||||
"videoRepeatActionSetEnd",
|
||||
"renameProcessorHash",
|
||||
"collectionActionSetHome",
|
||||
"setHomeCustomCollection",
|
||||
"settingsThumbnailShowHdrIcon",
|
||||
|
@ -1494,6 +1500,7 @@
|
|||
"renameEntrySetPageInsertTooltip",
|
||||
"renameEntrySetPagePreviewSectionTitle",
|
||||
"renameProcessorCounter",
|
||||
"renameProcessorHash",
|
||||
"renameProcessorName",
|
||||
"deleteSingleAlbumConfirmationDialogMessage",
|
||||
"deleteMultiAlbumConfirmationDialogMessage",
|
||||
|
@ -1930,6 +1937,7 @@
|
|||
"videoActionABRepeat",
|
||||
"videoRepeatActionSetStart",
|
||||
"videoRepeatActionSetEnd",
|
||||
"renameProcessorHash",
|
||||
"settingsForceWesternArabicNumeralsTile"
|
||||
],
|
||||
|
||||
|
@ -1939,6 +1947,7 @@
|
|||
"videoActionABRepeat",
|
||||
"videoRepeatActionSetStart",
|
||||
"videoRepeatActionSetEnd",
|
||||
"renameProcessorHash",
|
||||
"castDialogTitle",
|
||||
"aboutDataUsageSectionTitle",
|
||||
"aboutDataUsageData",
|
||||
|
@ -1956,6 +1965,7 @@
|
|||
],
|
||||
|
||||
"es": [
|
||||
"renameProcessorHash",
|
||||
"settingsForceWesternArabicNumeralsTile"
|
||||
],
|
||||
|
||||
|
@ -1964,6 +1974,7 @@
|
|||
"videoActionABRepeat",
|
||||
"videoRepeatActionSetStart",
|
||||
"videoRepeatActionSetEnd",
|
||||
"renameProcessorHash",
|
||||
"settingsForceWesternArabicNumeralsTile"
|
||||
],
|
||||
|
||||
|
@ -2011,6 +2022,7 @@
|
|||
"renameEntrySetPageInsertTooltip",
|
||||
"renameEntrySetPagePreviewSectionTitle",
|
||||
"renameProcessorCounter",
|
||||
"renameProcessorHash",
|
||||
"renameProcessorName",
|
||||
"deleteSingleAlbumConfirmationDialogMessage",
|
||||
"deleteMultiAlbumConfirmationDialogMessage",
|
||||
|
@ -2527,6 +2539,7 @@
|
|||
"renameEntrySetPageInsertTooltip",
|
||||
"renameEntrySetPagePreviewSectionTitle",
|
||||
"renameProcessorCounter",
|
||||
"renameProcessorHash",
|
||||
"renameProcessorName",
|
||||
"deleteSingleAlbumConfirmationDialogMessage",
|
||||
"deleteMultiAlbumConfirmationDialogMessage",
|
||||
|
@ -2959,6 +2972,7 @@
|
|||
],
|
||||
|
||||
"fr": [
|
||||
"renameProcessorHash",
|
||||
"settingsForceWesternArabicNumeralsTile"
|
||||
],
|
||||
|
||||
|
@ -3089,6 +3103,7 @@
|
|||
"renameEntrySetPageInsertTooltip",
|
||||
"renameEntrySetPagePreviewSectionTitle",
|
||||
"renameProcessorCounter",
|
||||
"renameProcessorHash",
|
||||
"renameProcessorName",
|
||||
"deleteSingleAlbumConfirmationDialogMessage",
|
||||
"deleteMultiAlbumConfirmationDialogMessage",
|
||||
|
@ -3775,6 +3790,7 @@
|
|||
"renameEntrySetPageInsertTooltip",
|
||||
"renameEntrySetPagePreviewSectionTitle",
|
||||
"renameProcessorCounter",
|
||||
"renameProcessorHash",
|
||||
"renameProcessorName",
|
||||
"deleteSingleAlbumConfirmationDialogMessage",
|
||||
"deleteMultiAlbumConfirmationDialogMessage",
|
||||
|
@ -4427,6 +4443,7 @@
|
|||
"renameEntrySetPageInsertTooltip",
|
||||
"renameEntrySetPagePreviewSectionTitle",
|
||||
"renameProcessorCounter",
|
||||
"renameProcessorHash",
|
||||
"renameProcessorName",
|
||||
"deleteSingleAlbumConfirmationDialogMessage",
|
||||
"deleteMultiAlbumConfirmationDialogMessage",
|
||||
|
@ -4859,10 +4876,12 @@
|
|||
],
|
||||
|
||||
"hu": [
|
||||
"renameProcessorHash",
|
||||
"settingsForceWesternArabicNumeralsTile"
|
||||
],
|
||||
|
||||
"id": [
|
||||
"renameProcessorHash",
|
||||
"settingsForceWesternArabicNumeralsTile"
|
||||
],
|
||||
|
||||
|
@ -4871,6 +4890,7 @@
|
|||
"videoActionABRepeat",
|
||||
"videoRepeatActionSetStart",
|
||||
"videoRepeatActionSetEnd",
|
||||
"renameProcessorHash",
|
||||
"settingsForceWesternArabicNumeralsTile"
|
||||
],
|
||||
|
||||
|
@ -4879,6 +4899,7 @@
|
|||
"videoActionABRepeat",
|
||||
"videoRepeatActionSetStart",
|
||||
"videoRepeatActionSetEnd",
|
||||
"renameProcessorHash",
|
||||
"collectionActionSetHome",
|
||||
"setHomeCustomCollection",
|
||||
"settingsThumbnailShowHdrIcon",
|
||||
|
@ -4911,6 +4932,7 @@
|
|||
"videoResumptionModeAlways",
|
||||
"widgetTapUpdateWidget",
|
||||
"vaultBinUsageDialogMessage",
|
||||
"renameProcessorHash",
|
||||
"exportEntryDialogQuality",
|
||||
"exportEntryDialogWriteMetadata",
|
||||
"castDialogTitle",
|
||||
|
@ -5172,6 +5194,7 @@
|
|||
"renameEntrySetPageInsertTooltip",
|
||||
"renameEntrySetPagePreviewSectionTitle",
|
||||
"renameProcessorCounter",
|
||||
"renameProcessorHash",
|
||||
"renameProcessorName",
|
||||
"deleteSingleAlbumConfirmationDialogMessage",
|
||||
"deleteMultiAlbumConfirmationDialogMessage",
|
||||
|
@ -5604,6 +5627,7 @@
|
|||
],
|
||||
|
||||
"ko": [
|
||||
"renameProcessorHash",
|
||||
"settingsForceWesternArabicNumeralsTile"
|
||||
],
|
||||
|
||||
|
@ -5661,6 +5685,7 @@
|
|||
"authenticateToConfigureVault",
|
||||
"authenticateToUnlockVault",
|
||||
"vaultBinUsageDialogMessage",
|
||||
"renameProcessorHash",
|
||||
"exportEntryDialogQuality",
|
||||
"exportEntryDialogWriteMetadata",
|
||||
"tooManyItemsErrorDialogMessage",
|
||||
|
@ -5964,6 +5989,7 @@
|
|||
"renameEntrySetPageInsertTooltip",
|
||||
"renameEntrySetPagePreviewSectionTitle",
|
||||
"renameProcessorCounter",
|
||||
"renameProcessorHash",
|
||||
"renameProcessorName",
|
||||
"deleteSingleAlbumConfirmationDialogMessage",
|
||||
"deleteMultiAlbumConfirmationDialogMessage",
|
||||
|
@ -6407,6 +6433,7 @@
|
|||
"widgetOpenPageHome",
|
||||
"widgetOpenPageCollection",
|
||||
"widgetOpenPageViewer",
|
||||
"renameProcessorHash",
|
||||
"menuActionConfigureView",
|
||||
"castDialogTitle",
|
||||
"aboutDataUsageClearCache",
|
||||
|
@ -6532,6 +6559,7 @@
|
|||
"settingsVideoEnablePip",
|
||||
"widgetTapUpdateWidget",
|
||||
"patternDialogEnter",
|
||||
"renameProcessorHash",
|
||||
"castDialogTitle",
|
||||
"aboutDataUsageInternal",
|
||||
"aboutDataUsageExternal",
|
||||
|
@ -6593,6 +6621,7 @@
|
|||
"authenticateToConfigureVault",
|
||||
"authenticateToUnlockVault",
|
||||
"vaultBinUsageDialogMessage",
|
||||
"renameProcessorHash",
|
||||
"exportEntryDialogQuality",
|
||||
"exportEntryDialogWriteMetadata",
|
||||
"tooManyItemsErrorDialogMessage",
|
||||
|
@ -6655,6 +6684,7 @@
|
|||
"widgetTapUpdateWidget",
|
||||
"authenticateToConfigureVault",
|
||||
"authenticateToUnlockVault",
|
||||
"renameProcessorHash",
|
||||
"viewDialogSortSectionTitle",
|
||||
"viewDialogReverseSortOrder",
|
||||
"castDialogTitle",
|
||||
|
@ -6922,6 +6952,7 @@
|
|||
"renameEntrySetPagePatternFieldLabel",
|
||||
"renameEntrySetPageInsertTooltip",
|
||||
"renameProcessorCounter",
|
||||
"renameProcessorHash",
|
||||
"deleteSingleAlbumConfirmationDialogMessage",
|
||||
"deleteMultiAlbumConfirmationDialogMessage",
|
||||
"exportEntryDialogFormat",
|
||||
|
@ -7306,10 +7337,12 @@
|
|||
],
|
||||
|
||||
"pl": [
|
||||
"renameProcessorHash",
|
||||
"settingsForceWesternArabicNumeralsTile"
|
||||
],
|
||||
|
||||
"pt": [
|
||||
"renameProcessorHash",
|
||||
"settingsForceWesternArabicNumeralsTile"
|
||||
],
|
||||
|
||||
|
@ -7318,10 +7351,12 @@
|
|||
"videoActionABRepeat",
|
||||
"videoRepeatActionSetStart",
|
||||
"videoRepeatActionSetEnd",
|
||||
"renameProcessorHash",
|
||||
"settingsForceWesternArabicNumeralsTile"
|
||||
],
|
||||
|
||||
"ru": [
|
||||
"renameProcessorHash",
|
||||
"settingsForceWesternArabicNumeralsTile"
|
||||
],
|
||||
|
||||
|
@ -7582,6 +7617,7 @@
|
|||
"renameEntrySetPageInsertTooltip",
|
||||
"renameEntrySetPagePreviewSectionTitle",
|
||||
"renameProcessorCounter",
|
||||
"renameProcessorHash",
|
||||
"renameProcessorName",
|
||||
"deleteSingleAlbumConfirmationDialogMessage",
|
||||
"deleteMultiAlbumConfirmationDialogMessage",
|
||||
|
@ -8018,6 +8054,7 @@
|
|||
"videoActionABRepeat",
|
||||
"videoRepeatActionSetStart",
|
||||
"videoRepeatActionSetEnd",
|
||||
"renameProcessorHash",
|
||||
"settingsForceWesternArabicNumeralsTile"
|
||||
],
|
||||
|
||||
|
@ -8276,6 +8313,7 @@
|
|||
"renameEntrySetPageInsertTooltip",
|
||||
"renameEntrySetPagePreviewSectionTitle",
|
||||
"renameProcessorCounter",
|
||||
"renameProcessorHash",
|
||||
"renameProcessorName",
|
||||
"deleteSingleAlbumConfirmationDialogMessage",
|
||||
"deleteMultiAlbumConfirmationDialogMessage",
|
||||
|
@ -8727,6 +8765,7 @@
|
|||
"renameAlbumDialogLabel",
|
||||
"renameAlbumDialogLabelAlreadyExistsHelper",
|
||||
"renameEntrySetPageTitle",
|
||||
"renameProcessorHash",
|
||||
"deleteSingleAlbumConfirmationDialogMessage",
|
||||
"deleteMultiAlbumConfirmationDialogMessage",
|
||||
"editEntryDialogTargetFieldsHeader",
|
||||
|
@ -9076,6 +9115,7 @@
|
|||
"authenticateToConfigureVault",
|
||||
"authenticateToUnlockVault",
|
||||
"vaultBinUsageDialogMessage",
|
||||
"renameProcessorHash",
|
||||
"exportEntryDialogQuality",
|
||||
"exportEntryDialogWriteMetadata",
|
||||
"editEntryDateDialogExtractFromTitle",
|
||||
|
@ -9430,10 +9470,12 @@
|
|||
],
|
||||
|
||||
"tr": [
|
||||
"renameProcessorHash",
|
||||
"settingsForceWesternArabicNumeralsTile"
|
||||
],
|
||||
|
||||
"uk": [
|
||||
"renameProcessorHash",
|
||||
"settingsForceWesternArabicNumeralsTile"
|
||||
],
|
||||
|
||||
|
@ -9442,6 +9484,7 @@
|
|||
"videoActionABRepeat",
|
||||
"videoRepeatActionSetStart",
|
||||
"videoRepeatActionSetEnd",
|
||||
"renameProcessorHash",
|
||||
"settingsForceWesternArabicNumeralsTile"
|
||||
],
|
||||
|
||||
|
@ -9450,6 +9493,7 @@
|
|||
"videoActionABRepeat",
|
||||
"videoRepeatActionSetStart",
|
||||
"videoRepeatActionSetEnd",
|
||||
"renameProcessorHash",
|
||||
"settingsForceWesternArabicNumeralsTile"
|
||||
],
|
||||
|
||||
|
@ -9458,6 +9502,7 @@
|
|||
"videoActionABRepeat",
|
||||
"videoRepeatActionSetStart",
|
||||
"videoRepeatActionSetEnd",
|
||||
"renameProcessorHash",
|
||||
"settingsForceWesternArabicNumeralsTile"
|
||||
]
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue