diff --git a/docs/screenshots/i18n-1.5.9/export-filename-zh-cn.jpg b/docs/screenshots/i18n-1.5.9/export-filename-zh-cn.jpg new file mode 100644 index 0000000000..afefd8562d Binary files /dev/null and b/docs/screenshots/i18n-1.5.9/export-filename-zh-cn.jpg differ diff --git a/docs/screenshots/i18n-1.5.9/import-settings-zh-cn.jpg b/docs/screenshots/i18n-1.5.9/import-settings-zh-cn.jpg new file mode 100644 index 0000000000..019fcc381b Binary files /dev/null and b/docs/screenshots/i18n-1.5.9/import-settings-zh-cn.jpg differ diff --git a/docs/screenshots/i18n-1.5.9/metadata-panel-zh-cn.jpg b/docs/screenshots/i18n-1.5.9/metadata-panel-zh-cn.jpg new file mode 100644 index 0000000000..036fd31d80 Binary files /dev/null and b/docs/screenshots/i18n-1.5.9/metadata-panel-zh-cn.jpg differ diff --git a/src-tauri/Info.plist b/src-tauri/Info.plist new file mode 100644 index 0000000000..a2ad5289d9 --- /dev/null +++ b/src-tauri/Info.plist @@ -0,0 +1,25 @@ + + + + + CFBundleAllowMixedLocalizations + + CFBundleDevelopmentRegion + en + CFBundleLocalizations + + en + de + es + fr + it + ja + ko + pl + pt + ru + zh-Hans + zh-Hant + + + diff --git a/src/components/modals/ImportSettingsModal.tsx b/src/components/modals/ImportSettingsModal.tsx index d777a9ec31..8707092d68 100644 --- a/src/components/modals/ImportSettingsModal.tsx +++ b/src/components/modals/ImportSettingsModal.tsx @@ -122,13 +122,14 @@ export default function ImportSettingsModal({ fileCount, isOpen, onClose, onSave value={filenameTemplate} />
- {FILENAME_VARIABLES.map((variable: string) => ( + {FILENAME_VARIABLES.map((variable) => ( ))}
diff --git a/src/components/modals/RenameFileModal.tsx b/src/components/modals/RenameFileModal.tsx index 341deb431d..69f37637fc 100644 --- a/src/components/modals/RenameFileModal.tsx +++ b/src/components/modals/RenameFileModal.tsx @@ -126,13 +126,14 @@ export default function RenameFileModal({ filesToRename, isOpen, onClose, onSave /> {!isSingleFile && (
- {FILENAME_VARIABLES.map((variable: string) => ( + {FILENAME_VARIABLES.map((variable) => ( ))}
diff --git a/src/components/panel/SettingsPanel.tsx b/src/components/panel/SettingsPanel.tsx index 86a6e0ea45..21537bc11a 100644 --- a/src/components/panel/SettingsPanel.tsx +++ b/src/components/panel/SettingsPanel.tsx @@ -45,6 +45,7 @@ import Text from '../ui/Text'; import { TextColors, TextVariants, TextWeights } from '../../types/typography'; import { useOsPlatform } from '../../hooks/useOsPlatform'; import { open } from '@tauri-apps/plugin-shell'; +import { translateBuiltInTag } from '../../i18n/translateBuiltInTag'; interface ConfirmModalState { confirmText: string; @@ -1467,11 +1468,13 @@ export default function SettingsPanel({ animate="visible" exit="exit" onClick={() => handleRemoveShortcut(shortcut)} - data-tooltip={t('settings.tagging.removeShortcutTooltip', { shortcut })} + data-tooltip={t('settings.tagging.removeShortcutTooltip', { + shortcut: translateBuiltInTag(shortcut), + })} className="flex items-center gap-1 bg-surface px-2 py-1 rounded-sm group cursor-pointer" > - {shortcut} + {translateBuiltInTag(shortcut)} @@ -2268,9 +2271,7 @@ export default function SettingsPanel({ buttonText={t('settings.data.clearSidecarsButton')} description={ - {t('settings.data.clearSidecarsDesc')}{' '} - .rrdata files - (containing your edits) within your root folders: + {t('settings.data.clearSidecarsDesc')} {effectiveRootPaths.length > 0 ? effectiveRootPaths.join('\n') diff --git a/src/components/panel/right/ExportPanel.tsx b/src/components/panel/right/ExportPanel.tsx index 583a788a3e..5331aa44f9 100644 --- a/src/components/panel/right/ExportPanel.tsx +++ b/src/components/panel/right/ExportPanel.tsx @@ -618,14 +618,15 @@ export default function ExportPanel({ value={filenameTemplate} />
- {FILENAME_VARIABLES.map((variable: string) => ( + {FILENAME_VARIABLES.map((variable) => ( ))}
diff --git a/src/components/panel/right/MetadataPanel.tsx b/src/components/panel/right/MetadataPanel.tsx index 0932e72ec1..6e040305ce 100644 --- a/src/components/panel/right/MetadataPanel.tsx +++ b/src/components/panel/right/MetadataPanel.tsx @@ -2,6 +2,7 @@ import { useState, useMemo, useEffect } from 'react'; import { invoke } from '@tauri-apps/api/core'; import { Check, ChevronDown, ChevronRight, Plus, Star, Tag, X, User } from 'lucide-react'; import { motion, AnimatePresence } from 'framer-motion'; +import i18n from 'i18next'; import { useTranslation } from 'react-i18next'; import clsx from 'clsx'; import { Invokes } from '../../ui/AppProperties'; @@ -14,6 +15,7 @@ import { useLibraryStore } from '../../../store/useLibraryStore'; import { useSettingsStore } from '../../../store/useSettingsStore'; import { useProcessStore } from '../../../store/useProcessStore'; import { useLibraryActions } from '../../../hooks/useLibraryActions'; +import { translateBuiltInTag } from '../../../i18n/translateBuiltInTag'; interface CameraSetting { format?(value: number): string | number; @@ -47,6 +49,164 @@ function formatExifTag(str: string) { return str.replace(/([a-z])([A-Z])/g, '$1 $2').replace(/([A-Z])([A-Z][a-z])/g, '$1 $2'); } +const EXIF_FIELD_TRANSLATION_KEYS: Record = { + ApertureValue: 'editor.metadata.extendedExif.fields.apertureValue', + Artist: 'editor.metadata.extendedExif.fields.artist', + BitsPerSample: 'editor.metadata.extendedExif.fields.bitsPerSample', + BodySerialNumber: 'editor.metadata.extendedExif.fields.bodySerialNumber', + BrightnessValue: 'editor.metadata.extendedExif.fields.brightnessValue', + CameraSerialNumber: 'editor.metadata.extendedExif.fields.cameraSerialNumber', + ColorSpace: 'editor.metadata.extendedExif.fields.colorSpace', + ComponentsConfiguration: 'editor.metadata.extendedExif.fields.componentsConfiguration', + Compression: 'editor.metadata.extendedExif.fields.compression', + Contrast: 'editor.metadata.extendedExif.fields.contrast', + Copyright: 'editor.metadata.extendedExif.fields.copyright', + CreateDate: 'editor.metadata.extendedExif.fields.createDate', + CustomRendered: 'editor.metadata.extendedExif.fields.customRendered', + DateTime: 'editor.metadata.extendedExif.fields.createDate', + DateTimeDigitized: 'editor.metadata.extendedExif.fields.modifyDate', + DateTimeOriginal: 'editor.metadata.extendedExif.fields.dateTimeOriginal', + DigitalZoomRatio: 'editor.metadata.extendedExif.fields.digitalZoomRatio', + ExifVersion: 'editor.metadata.extendedExif.fields.exifVersion', + ExposureBiasValue: 'editor.metadata.extendedExif.fields.exposureBiasValue', + ExposureIndex: 'editor.metadata.extendedExif.fields.exposureIndex', + ExposureMode: 'editor.metadata.extendedExif.fields.exposureMode', + ExposureProgram: 'editor.metadata.extendedExif.fields.exposureProgram', + FileSource: 'editor.metadata.extendedExif.fields.fileSource', + Flash: 'editor.metadata.extendedExif.fields.flash', + FlashpixVersion: 'editor.metadata.extendedExif.fields.flashpixVersion', + FocalLength: 'editor.metadata.extendedExif.fields.focalLength', + FocalLengthIn35mmFormat: 'editor.metadata.extendedExif.fields.focalLengthIn35mmFormat', + FocalPlaneResolutionUnit: 'editor.metadata.extendedExif.fields.focalPlaneResolutionUnit', + FocalPlaneXResolution: 'editor.metadata.extendedExif.fields.focalPlaneXResolution', + FocalPlaneYResolution: 'editor.metadata.extendedExif.fields.focalPlaneYResolution', + GainControl: 'editor.metadata.extendedExif.fields.gainControl', + ImageDescription: 'editor.metadata.extendedExif.fields.imageDescription', + ImageHeight: 'editor.metadata.extendedExif.fields.imageHeight', + ImageLength: 'editor.metadata.extendedExif.fields.imageLength', + ImageUniqueID: 'editor.metadata.extendedExif.fields.imageUniqueId', + ImageWidth: 'editor.metadata.extendedExif.fields.imageWidth', + ISOSpeed: 'editor.metadata.extendedExif.fields.isoSpeed', + LensMake: 'editor.metadata.extendedExif.fields.lensMake', + LensModel: 'editor.metadata.extendedExif.fields.lensModel', + LensSerialNumber: 'editor.metadata.extendedExif.fields.lensSerialNumber', + LensSpecification: 'editor.metadata.extendedExif.fields.lensSpecification', + LightSource: 'editor.metadata.extendedExif.fields.lightSource', + Make: 'editor.metadata.extendedExif.fields.make', + MaxApertureValue: 'editor.metadata.extendedExif.fields.maxApertureValue', + MeteringMode: 'editor.metadata.extendedExif.fields.meteringMode', + Model: 'editor.metadata.extendedExif.fields.model', + ModifyDate: 'editor.metadata.extendedExif.fields.modifyDate', + OffsetTime: 'editor.metadata.extendedExif.fields.offsetTime', + OffsetTimeDigitized: 'editor.metadata.extendedExif.fields.offsetTimeDigitized', + OffsetTimeOriginal: 'editor.metadata.extendedExif.fields.offsetTimeOriginal', + Orientation: 'editor.metadata.extendedExif.fields.orientation', + PhotometricInterpretation: 'editor.metadata.extendedExif.fields.photometricInterpretation', + PhotographicSensitivity: 'editor.metadata.extendedExif.fields.photographicSensitivity', + PixelXDimension: 'editor.metadata.extendedExif.fields.pixelXDimension', + PixelYDimension: 'editor.metadata.extendedExif.fields.pixelYDimension', + PlanarConfiguration: 'editor.metadata.extendedExif.fields.planarConfiguration', + RecommendedExposureIndex: 'editor.metadata.extendedExif.fields.recommendedExposureIndex', + ResolutionUnit: 'editor.metadata.extendedExif.fields.resolutionUnit', + RowsPerStrip: 'editor.metadata.extendedExif.fields.rowsPerStrip', + Saturation: 'editor.metadata.extendedExif.fields.saturation', + SamplesPerPixel: 'editor.metadata.extendedExif.fields.samplesPerPixel', + SceneCaptureType: 'editor.metadata.extendedExif.fields.sceneCaptureType', + SceneType: 'editor.metadata.extendedExif.fields.sceneType', + SensingMethod: 'editor.metadata.extendedExif.fields.sensingMethod', + SensitivityType: 'editor.metadata.extendedExif.fields.sensitivityType', + Sharpness: 'editor.metadata.extendedExif.fields.sharpness', + ShutterSpeedValue: 'editor.metadata.extendedExif.fields.shutterSpeedValue', + Software: 'editor.metadata.extendedExif.fields.software', + StripByteCounts: 'editor.metadata.extendedExif.fields.stripByteCounts', + StripOffsets: 'editor.metadata.extendedExif.fields.stripOffsets', + SubSecTimeDigitized: 'editor.metadata.extendedExif.fields.subSecTimeDigitized', + SubSecTimeOriginal: 'editor.metadata.extendedExif.fields.subSecTimeOriginal', + SubjectDistance: 'editor.metadata.extendedExif.fields.subjectDistance', + UserComment: 'editor.metadata.extendedExif.fields.userComment', + WhiteBalance: 'editor.metadata.extendedExif.fields.whiteBalance', + XResolution: 'editor.metadata.extendedExif.fields.xResolution', + YResolution: 'editor.metadata.extendedExif.fields.yResolution', +}; + +const EXIF_VALUE_TRANSLATION_KEYS: Record> = { + Compression: { + uncompressed: 'editor.metadata.extendedExif.values.uncompressed', + }, + Contrast: { + normal: 'editor.metadata.extendedExif.values.normal', + }, + CustomRendered: { + 'normal process': 'editor.metadata.extendedExif.values.normalProcess', + }, + ExposureMode: { + 'auto exposure': 'editor.metadata.extendedExif.values.autoExposure', + 'manual exposure': 'editor.metadata.extendedExif.values.manualExposure', + }, + ExposureProgram: { + manual: 'editor.metadata.extendedExif.values.manual', + }, + FileSource: { + 'digital still camera': 'editor.metadata.extendedExif.values.digitalStillCamera', + }, + Flash: { + 'fired, return light detected': 'editor.metadata.extendedExif.values.flashFiredReturnDetected', + 'fired, return light not detected': 'editor.metadata.extendedExif.values.flashFiredReturnNotDetected', + 'fired, return light not detected, forced': 'editor.metadata.extendedExif.values.flashFiredReturnNotDetectedForced', + 'flash did not fire': 'editor.metadata.extendedExif.values.flashDidNotFire', + 'no flash': 'editor.metadata.extendedExif.values.noFlash', + }, + MeteringMode: { + pattern: 'editor.metadata.extendedExif.values.patternMetering', + }, + Orientation: { + 'row 0 at top and column 0 at left': 'editor.metadata.extendedExif.values.topLeft', + }, + PlanarConfiguration: { + chunky: 'editor.metadata.extendedExif.values.chunky', + }, + Saturation: { + normal: 'editor.metadata.extendedExif.values.normal', + }, + SceneCaptureType: { + landscape: 'editor.metadata.extendedExif.values.landscape', + portrait: 'editor.metadata.extendedExif.values.portrait', + standard: 'editor.metadata.extendedExif.values.standard', + }, + SceneType: { + 'directly photographed': 'editor.metadata.extendedExif.values.directlyPhotographed', + 'directly photographed image': 'editor.metadata.extendedExif.values.directlyPhotographed', + }, + Sharpness: { + normal: 'editor.metadata.extendedExif.values.normal', + }, + WhiteBalance: { + auto: 'editor.metadata.extendedExif.values.auto', + 'auto white balance': 'editor.metadata.extendedExif.values.auto', + manual: 'editor.metadata.extendedExif.values.manual', + 'manual white balance': 'editor.metadata.extendedExif.values.manual', + }, +}; + +function translateExtendedExifTag(tag: string): string { + const translationKey = EXIF_FIELD_TRANSLATION_KEYS[tag]; + if (translationKey) return String(i18n.t(translationKey as never)); + + const tiffTagMatch = tag.match(/^Tag\(Tiff,\s*(\d+)\)$/i); + if (tiffTagMatch) { + return String(i18n.t('editor.metadata.extendedExif.unknownTiffTag', { id: tiffTagMatch[1] })); + } + + return formatExifTag(tag); +} + +function translateExtendedExifValue(tag: string, value: unknown) { + if (typeof value !== 'string') return value; + const normalizedValue = value.trim().toLowerCase().replace(/\s+/g, ' '); + const translationKey = EXIF_VALUE_TRANSLATION_KEYS[tag]?.[normalizedValue]; + return translationKey ? String(i18n.t(translationKey as never)) : value; +} + function parseDms(dmsString: string) { if (!dmsString) return null; const parts = dmsString.match(/(\d+\.?\d*)\s+deg\s+(\d+\.?\d*)\s+min\s+(\d+\.?\d*)\s+sec/); @@ -681,7 +841,7 @@ export default function MetadataPanel() { color={TextColors.primary} weight={TextWeights.medium} > - {tagItem.tag} + {translateBuiltInTag(tagItem.tag)}
@@ -726,7 +886,7 @@ export default function MetadataPanel() { onClick={() => handleAddTag(shortcut)} className="text-xs font-medium bg-bg-secondary hover:bg-card-active text-text-secondary px-1.5 py-0.5 rounded-sm border border-transparent hover:border-border-color transition-all" > - {shortcut} + {translateBuiltInTag(shortcut)} ))} @@ -787,7 +947,11 @@ export default function MetadataPanel() {
{otherExifEntries.map(([tag, value]) => ( - + ))}
diff --git a/src/components/ui/ExportImportProperties.tsx b/src/components/ui/ExportImportProperties.tsx index a51dff33a5..d1ddb0e0c0 100644 --- a/src/components/ui/ExportImportProperties.tsx +++ b/src/components/ui/ExportImportProperties.tsx @@ -23,15 +23,15 @@ export const FILE_FORMATS: Array = [ { id: FileFormats.Cube, name: 'CUBE LUT', extensions: ['cube'] }, ]; -export const FILENAME_VARIABLES: Array = [ - '{original_filename}', - '{sequence}', - '{YYYY}', - '{MM}', - '{DD}', - '{hh}', - '{mm}', -]; +export const FILENAME_VARIABLES = [ + { token: '{original_filename}', labelKey: 'ui.filenameVariables.originalFilename' }, + { token: '{sequence}', labelKey: 'ui.filenameVariables.sequence' }, + { token: '{YYYY}', labelKey: 'ui.filenameVariables.year' }, + { token: '{MM}', labelKey: 'ui.filenameVariables.month' }, + { token: '{DD}', labelKey: 'ui.filenameVariables.day' }, + { token: '{hh}', labelKey: 'ui.filenameVariables.hour' }, + { token: '{mm}', labelKey: 'ui.filenameVariables.minute' }, +] as const; export interface ExportSettings { filenameTemplate: string | null; diff --git a/src/context/TaggingSubMenu.tsx b/src/context/TaggingSubMenu.tsx index b6c00f9406..af711ba8b6 100644 --- a/src/context/TaggingSubMenu.tsx +++ b/src/context/TaggingSubMenu.tsx @@ -6,6 +6,7 @@ import { useTranslation } from 'react-i18next'; import { Invokes } from '../components/ui/AppProperties'; import Text from '../components/ui/Text'; import { TextVariants } from '../types/typography'; +import { translateBuiltInTag } from '../i18n/translateBuiltInTag'; interface TaggingSubMenuProps { paths: string[]; @@ -101,10 +102,10 @@ export default function TaggingSubMenu({ animate="visible" exit="exit" onClick={() => handleRemoveTag(tagItem)} - data-tooltip={t('menus.tagging.removeTooltip', { tag: tagItem.tag })} + data-tooltip={t('menus.tagging.removeTooltip', { tag: translateBuiltInTag(tagItem.tag) })} className="flex items-center gap-1 bg-bg-primary text-text-primary text-xs font-medium px-2 py-1 rounded-sm group cursor-pointer" > - {tagItem.tag} + {translateBuiltInTag(tagItem.tag)} @@ -157,7 +158,7 @@ export default function TaggingSubMenu({ onClick={() => handleAddTag(shortcut)} className="bg-surface text-text-secondary hover:bg-card-active hover:text-text-primary text-xs font-medium px-2 py-1 rounded-sm" > - {shortcut} + {translateBuiltInTag(shortcut)} ))} diff --git a/src/hooks/useFileOperations.ts b/src/hooks/useFileOperations.ts index 76f7837abe..af3a3706cb 100644 --- a/src/hooks/useFileOperations.ts +++ b/src/hooks/useFileOperations.ts @@ -1,4 +1,5 @@ import { useCallback } from 'react'; +import { useTranslation } from 'react-i18next'; import { invoke } from '@tauri-apps/api/core'; import { open } from '@tauri-apps/plugin-dialog'; import { toast } from 'react-toastify'; @@ -17,6 +18,8 @@ export function useFileOperations( handleBackToLibrary: () => void, sortedImageList: any[], ) { + const { t } = useTranslation(); + const getParentDir = (filePath: string): string => { const separator = filePath.includes('/') ? '/' : '\\'; const lastSeparatorIndex = filePath.lastIndexOf(separator); @@ -299,16 +302,22 @@ export function useFileOperations( const typeFilters = isAndroid ? [] : [ - { name: 'All Supported Images', extensions: allImageExtensions }, - { name: 'RAW Images', extensions: processedRaw }, - { name: 'Standard Images (JPEG, PNG, etc.)', extensions: processedNonRaw }, - { name: 'All Files', extensions: ['*'] }, + { + name: t('modals.importSettings.fileDialog.allSupportedImages'), + extensions: allImageExtensions, + }, + { name: t('modals.importSettings.fileDialog.rawImages'), extensions: processedRaw }, + { + name: t('modals.importSettings.fileDialog.standardImages'), + extensions: processedNonRaw, + }, + { name: t('modals.importSettings.fileDialog.allFiles'), extensions: ['*'] }, ]; const selected = await open({ filters: typeFilters, multiple: true, - title: 'Select files to import', + title: t('modals.importSettings.fileDialog.selectFilesTitle'), }); if (Array.isArray(selected) && selected.length > 0) { @@ -342,7 +351,7 @@ export function useFileOperations( if (invalidExtensions.size > 0) { const extList = Array.from(invalidExtensions).join(', '); - toast.error(`Unsupported file format(s) detected: ${extList}`); + toast.error(t('modals.importSettings.fileDialog.unsupportedFormats', { formats: extList })); return; } @@ -363,7 +372,7 @@ export function useFileOperations( console.error('Failed to open file dialog for import:', err); } }, - [startImportFiles], + [startImportFiles, t], ); const handlePasteFiles = useCallback( diff --git a/src/i18n/locales/de.json b/src/i18n/locales/de.json index a9961e9918..30c4cea01b 100644 --- a/src/i18n/locales/de.json +++ b/src/i18n/locales/de.json @@ -615,7 +615,8 @@ "copy": "Kopieren", "emptyClickToAdd": "Leer (Klicken zum Hinzufügen)", "extendedExif": { - "title": "Erweiterte EXIF" + "title": "Erweiterte EXIF", + "unknownTiffTag": "TIFF-Tag ({{id}})" }, "fields": { "author": "Autor", @@ -1233,6 +1234,14 @@ "dateFormatPlaceholder": "z. B., YYYY/MM-DD", "deleteAfterImport": "Originale nach erfolgreichem Import löschen", "deleteWarning": "Dateien werden in den Systempapierkorb verschoben.", + "fileDialog": { + "allFiles": "Alle Dateien", + "allSupportedImages": "Alle unterstützten Bilder", + "rawImages": "RAW-Bilder", + "selectFilesTitle": "Dateien zum Importieren auswählen", + "standardImages": "Standardbilder (JPEG, PNG usw.)", + "unsupportedFormats": "Nicht unterstützte Dateiformate erkannt: {{formats}}" + }, "fileNaming": "Dateibenennung", "folderOrganization": "Ordnerorganisation", "organizeByDate": "In Unterordner nach Datum organisieren", @@ -1731,6 +1740,17 @@ } }, "ui": { + "builtInTags": { + "architecture": "Architektur", + "event": "Veranstaltung", + "family": "Familie", + "food": "Essen", + "landscape": "Landschaft", + "nature": "Natur", + "portrait": "Porträt", + "street": "Streetfotografie", + "travel": "Reisen" + }, "bottomBar": { "imagesSelected": "{{current}} von {{total}} Bildern ausgewählt", "tooltips": { @@ -1771,6 +1791,15 @@ "saveAsNewTooltip": "Aktuelle Einstellungen als neue Vorgabe speichern", "savedTooltip": "Gespeichert!" }, + "filenameVariables": { + "day": "Tag", + "hour": "Stunde", + "minute": "Minute", + "month": "Monat", + "originalFilename": "Ursprünglicher Dateiname", + "sequence": "Sequenz", + "year": "Jahr" + }, "filmstrip": { "tooltips": { "color": "Farbe: {{color}}", diff --git a/src/i18n/locales/en.json b/src/i18n/locales/en.json index 4c8818a6e0..5d17ac4aad 100644 --- a/src/i18n/locales/en.json +++ b/src/i18n/locales/en.json @@ -615,7 +615,108 @@ "copy": "Copy", "emptyClickToAdd": "Empty (Click to add)", "extendedExif": { - "title": "Extended EXIF" + "fields": { + "apertureValue": "Aperture Value", + "artist": "Artist", + "bitsPerSample": "Bits Per Sample", + "bodySerialNumber": "Body Serial Number", + "brightnessValue": "Brightness Value", + "cameraSerialNumber": "Camera Serial Number", + "colorSpace": "Color Space", + "componentsConfiguration": "Components Configuration", + "compression": "Compression", + "contrast": "Contrast", + "copyright": "Copyright", + "createDate": "Create Date", + "customRendered": "Custom Rendered", + "dateTimeOriginal": "Date/Time Original", + "digitalZoomRatio": "Digital Zoom Ratio", + "exifVersion": "EXIF Version", + "exposureBiasValue": "Exposure Bias Value", + "exposureIndex": "Exposure Index", + "exposureMode": "Exposure Mode", + "exposureProgram": "Exposure Program", + "fileSource": "File Source", + "flash": "Flash", + "flashpixVersion": "Flashpix Version", + "focalLength": "Focal Length", + "focalLengthIn35mmFormat": "Focal Length in 35mm Format", + "focalPlaneResolutionUnit": "Focal Plane Resolution Unit", + "focalPlaneXResolution": "Focal Plane X Resolution", + "focalPlaneYResolution": "Focal Plane Y Resolution", + "gainControl": "Gain Control", + "imageDescription": "Image Description", + "imageHeight": "Image Height", + "imageLength": "Image Length", + "imageUniqueId": "Image Unique ID", + "imageWidth": "Image Width", + "isoSpeed": "ISO Speed", + "lensMake": "Lens Make", + "lensModel": "Lens Model", + "lensSerialNumber": "Lens Serial Number", + "lensSpecification": "Lens Specification", + "lightSource": "Light Source", + "make": "Camera Make", + "maxApertureValue": "Max Aperture Value", + "meteringMode": "Metering Mode", + "model": "Camera Model", + "modifyDate": "Modify Date", + "offsetTime": "Offset Time", + "offsetTimeDigitized": "Offset Time Digitized", + "offsetTimeOriginal": "Offset Time Original", + "orientation": "Orientation", + "photometricInterpretation": "Photometric Interpretation", + "photographicSensitivity": "Photographic Sensitivity", + "pixelXDimension": "Pixel X Dimension", + "pixelYDimension": "Pixel Y Dimension", + "planarConfiguration": "Planar Configuration", + "recommendedExposureIndex": "Recommended Exposure Index", + "resolutionUnit": "Resolution Unit", + "rowsPerStrip": "Rows Per Strip", + "saturation": "Saturation", + "samplesPerPixel": "Samples Per Pixel", + "sceneCaptureType": "Scene Capture Type", + "sceneType": "Scene Type", + "sensingMethod": "Sensing Method", + "sensitivityType": "Sensitivity Type", + "sharpness": "Sharpness", + "shutterSpeedValue": "Shutter Speed Value", + "software": "Software", + "stripByteCounts": "Strip Byte Counts", + "stripOffsets": "Strip Offsets", + "subSecTimeDigitized": "Sub-second Time Digitized", + "subSecTimeOriginal": "Sub-second Time Original", + "subjectDistance": "Subject Distance", + "userComment": "User Comment", + "whiteBalance": "White Balance", + "xResolution": "X Resolution", + "yResolution": "Y Resolution" + }, + "title": "Extended EXIF", + "unknownTiffTag": "TIFF Tag ({{id}})", + "values": { + "auto": "Auto", + "autoExposure": "Auto exposure", + "chunky": "Chunky", + "digitalStillCamera": "Digital still camera", + "directlyPhotographed": "Directly photographed", + "flashDidNotFire": "Flash did not fire", + "flashFiredReturnDetected": "Fired, return light detected", + "flashFiredReturnNotDetected": "Fired, return light not detected", + "flashFiredReturnNotDetectedForced": "Fired, return light not detected, forced", + "landscape": "Landscape", + "manual": "Manual", + "manualExposure": "Manual exposure", + "noFlash": "No flash", + "normal": "Normal", + "normalProcess": "Normal process", + "patternMetering": "Pattern", + "portrait": "Portrait", + "standard": "Standard", + "topLeft": "Top-left", + "uncompressed": "Uncompressed", + "unknown": "Unknown" + } }, "fields": { "author": "Author", @@ -1233,6 +1334,14 @@ "dateFormatPlaceholder": "e.g., YYYY/MM-DD", "deleteAfterImport": "Delete originals after successful import", "deleteWarning": "Files will be moved to the system trash.", + "fileDialog": { + "allFiles": "All Files", + "allSupportedImages": "All Supported Images", + "rawImages": "RAW Images", + "selectFilesTitle": "Select files to import", + "standardImages": "Standard Images (JPEG, PNG, etc.)", + "unsupportedFormats": "Unsupported file format(s) detected: {{formats}}" + }, "fileNaming": "File Naming", "folderOrganization": "Folder Organization", "organizeByDate": "Organize into subfolders by date", @@ -1731,6 +1840,17 @@ } }, "ui": { + "builtInTags": { + "architecture": "Architecture", + "event": "Event", + "family": "Family", + "food": "Food", + "landscape": "Landscape", + "nature": "Nature", + "portrait": "Portrait", + "street": "Street", + "travel": "Travel" + }, "bottomBar": { "imagesSelected": "{{current}} of {{total}} images selected", "tooltips": { @@ -1771,6 +1891,15 @@ "saveAsNewTooltip": "Save current settings as new preset", "savedTooltip": "Saved!" }, + "filenameVariables": { + "day": "Day", + "hour": "Hour", + "minute": "Minute", + "month": "Month", + "originalFilename": "Original filename", + "sequence": "Sequence", + "year": "Year" + }, "filmstrip": { "tooltips": { "color": "Color: {{color}}", diff --git a/src/i18n/locales/es.json b/src/i18n/locales/es.json index 68db75e4ea..e11433f49b 100644 --- a/src/i18n/locales/es.json +++ b/src/i18n/locales/es.json @@ -636,7 +636,8 @@ "copy": "Copiar", "emptyClickToAdd": "Vacío (Haz clic para añadir)", "extendedExif": { - "title": "EXIF Extendido" + "title": "EXIF Extendido", + "unknownTiffTag": "Etiqueta TIFF ({{id}})" }, "fields": { "author": "Autor", @@ -1260,6 +1261,14 @@ "dateFormatPlaceholder": "ej., AAAA/MM-DD", "deleteAfterImport": "Eliminar originales tras una importación exitosa", "deleteWarning": "Los archivos se moverán a la papelera del sistema.", + "fileDialog": { + "allFiles": "Todos los archivos", + "allSupportedImages": "Todas las imágenes compatibles", + "rawImages": "Imágenes RAW", + "selectFilesTitle": "Seleccionar archivos para importar", + "standardImages": "Imágenes estándar (JPEG, PNG, etc.)", + "unsupportedFormats": "Se detectaron formatos de archivo no compatibles: {{formats}}" + }, "fileNaming": "Nomenclatura de archivos", "folderOrganization": "Organización de carpetas", "organizeByDate": "Organizar en subcarpetas por fecha", @@ -1764,6 +1773,17 @@ } }, "ui": { + "builtInTags": { + "architecture": "Arquitectura", + "event": "Evento", + "family": "Familia", + "food": "Comida", + "landscape": "Paisaje", + "nature": "Naturaleza", + "portrait": "Retrato", + "street": "Calle", + "travel": "Viaje" + }, "bottomBar": { "imagesSelected": "{{current}} de {{total}} imágenes seleccionadas", "tooltips": { @@ -1805,6 +1825,15 @@ "saveAsNewTooltip": "Guardar los ajustes actuales como un nuevo ajuste preestablecido", "savedTooltip": "¡Guardado!" }, + "filenameVariables": { + "day": "Día", + "hour": "Hora", + "minute": "Minuto", + "month": "Mes", + "originalFilename": "Nombre de archivo original", + "sequence": "Secuencia", + "year": "Año" + }, "filmstrip": { "tooltips": { "color": "Color: {{color}}", diff --git a/src/i18n/locales/fr.json b/src/i18n/locales/fr.json index 33673c3818..089b323484 100644 --- a/src/i18n/locales/fr.json +++ b/src/i18n/locales/fr.json @@ -636,7 +636,8 @@ "copy": "Copier", "emptyClickToAdd": "Vide (cliquer pour ajouter)", "extendedExif": { - "title": "EXIF étendu" + "title": "EXIF étendu", + "unknownTiffTag": "Balise TIFF ({{id}})" }, "fields": { "author": "Auteur", @@ -1260,6 +1261,14 @@ "dateFormatPlaceholder": "ex. : AAAA/MM-JJ", "deleteAfterImport": "Supprimer les originaux après importation réussie", "deleteWarning": "Les fichiers seront déplacés vers la corbeille du système.", + "fileDialog": { + "allFiles": "Tous les fichiers", + "allSupportedImages": "Toutes les images prises en charge", + "rawImages": "Images RAW", + "selectFilesTitle": "Sélectionner les fichiers à importer", + "standardImages": "Images standard (JPEG, PNG, etc.)", + "unsupportedFormats": "Formats de fichier non pris en charge détectés : {{formats}}" + }, "fileNaming": "Nommage des fichiers", "folderOrganization": "Organisation des dossiers", "organizeByDate": "Organiser dans des sous-dossiers par date", @@ -1764,6 +1773,17 @@ } }, "ui": { + "builtInTags": { + "architecture": "Architecture", + "event": "Événement", + "family": "Famille", + "food": "Cuisine", + "landscape": "Paysage", + "nature": "Nature", + "portrait": "Portrait", + "street": "Rue", + "travel": "Voyage" + }, "bottomBar": { "imagesSelected": "{{current}} sur {{total}} images sélectionnées", "tooltips": { @@ -1805,6 +1825,15 @@ "saveAsNewTooltip": "Enregistrer les paramètres actuels comme nouveau", "savedTooltip": "Enregistré !" }, + "filenameVariables": { + "day": "Jour", + "hour": "Heure", + "minute": "Minute", + "month": "Mois", + "originalFilename": "Nom de fichier d’origine", + "sequence": "Séquence", + "year": "Année" + }, "filmstrip": { "tooltips": { "color": "Couleur : {{color}}", diff --git a/src/i18n/locales/it.json b/src/i18n/locales/it.json index eb65c62d6e..00b7c8b2c1 100644 --- a/src/i18n/locales/it.json +++ b/src/i18n/locales/it.json @@ -636,7 +636,8 @@ "copy": "Copia", "emptyClickToAdd": "Vuoto (Clicca per aggiungere)", "extendedExif": { - "title": "EXIF Estesi" + "title": "EXIF Estesi", + "unknownTiffTag": "Tag TIFF ({{id}})" }, "fields": { "author": "Autore", @@ -1260,6 +1261,14 @@ "dateFormatPlaceholder": "es. YYYY/MM-DD", "deleteAfterImport": "Elimina originali dopo importazione completata", "deleteWarning": "I file verranno spostati nel cestino di sistema.", + "fileDialog": { + "allFiles": "Tutti i file", + "allSupportedImages": "Tutte le immagini supportate", + "rawImages": "Immagini RAW", + "selectFilesTitle": "Seleziona i file da importare", + "standardImages": "Immagini standard (JPEG, PNG, ecc.)", + "unsupportedFormats": "Rilevati formati di file non supportati: {{formats}}" + }, "fileNaming": "Nomenclatura File", "folderOrganization": "Organizzazione Cartelle", "organizeByDate": "Organizza in sottocartelle per data", @@ -1764,6 +1773,17 @@ } }, "ui": { + "builtInTags": { + "architecture": "Architettura", + "event": "Evento", + "family": "Famiglia", + "food": "Cibo", + "landscape": "Paesaggio", + "nature": "Natura", + "portrait": "Ritratto", + "street": "Strada", + "travel": "Viaggio" + }, "bottomBar": { "imagesSelected": "{{current}} di {{total}} immagini selezionate", "tooltips": { @@ -1805,6 +1825,15 @@ "saveAsNewTooltip": "Salva le impostazioni attuali come nuovo predefinito", "savedTooltip": "Salvato!" }, + "filenameVariables": { + "day": "Giorno", + "hour": "Ora", + "minute": "Minuto", + "month": "Mese", + "originalFilename": "Nome file originale", + "sequence": "Sequenza", + "year": "Anno" + }, "filmstrip": { "tooltips": { "color": "Colore: {{color}}", diff --git a/src/i18n/locales/ja.json b/src/i18n/locales/ja.json index ecd9c6e46f..6a51d23065 100644 --- a/src/i18n/locales/ja.json +++ b/src/i18n/locales/ja.json @@ -613,7 +613,8 @@ "copy": "コピー", "emptyClickToAdd": "未設定 (クリックして追加)", "extendedExif": { - "title": "拡張EXIF" + "title": "拡張EXIF", + "unknownTiffTag": "TIFF タグ({{id}})" }, "fields": { "author": "作成者", @@ -1231,6 +1232,14 @@ "dateFormatPlaceholder": "例: YYYY/MM-DD", "deleteAfterImport": "インポート完了後に元のファイルを削除", "deleteWarning": "ファイルはシステムのゴミ箱に移動されます。", + "fileDialog": { + "allFiles": "すべてのファイル", + "allSupportedImages": "対応するすべての画像", + "rawImages": "RAW 画像", + "selectFilesTitle": "インポートするファイルを選択", + "standardImages": "標準画像(JPEG、PNG など)", + "unsupportedFormats": "対応していないファイル形式が検出されました: {{formats}}" + }, "fileNaming": "ファイル名の命名", "folderOrganization": "フォルダ構成", "organizeByDate": "日付ごとにサブフォルダに整理する", @@ -1729,6 +1738,17 @@ } }, "ui": { + "builtInTags": { + "architecture": "建築", + "event": "イベント", + "family": "家族", + "food": "食べ物", + "landscape": "風景", + "nature": "自然", + "portrait": "ポートレート", + "street": "ストリート", + "travel": "旅行" + }, "bottomBar": { "imagesSelected": "{{total}}枚中 {{current}}枚の画像を選択中", "tooltips": { @@ -1769,6 +1789,15 @@ "saveAsNewTooltip": "現在の設定を新規プリセットとして保存", "savedTooltip": "保存しました!" }, + "filenameVariables": { + "day": "日", + "hour": "時", + "minute": "分", + "month": "月", + "originalFilename": "元のファイル名", + "sequence": "連番", + "year": "年" + }, "filmstrip": { "tooltips": { "color": "カラー: {{color}}", diff --git a/src/i18n/locales/ko.json b/src/i18n/locales/ko.json index 8db0ec1a5a..197c1acc1a 100644 --- a/src/i18n/locales/ko.json +++ b/src/i18n/locales/ko.json @@ -613,7 +613,8 @@ "copy": "복사", "emptyClickToAdd": "비어 있음 (클릭하여 추가)", "extendedExif": { - "title": "확장 EXIF" + "title": "확장 EXIF", + "unknownTiffTag": "TIFF 태그({{id}})" }, "fields": { "author": "작성자", @@ -1231,6 +1232,14 @@ "dateFormatPlaceholder": "예: YYYY/MM-DD", "deleteAfterImport": "가져오기 성공 후 원본 삭제", "deleteWarning": "파일이 시스템 휴지통으로 이동됩니다.", + "fileDialog": { + "allFiles": "모든 파일", + "allSupportedImages": "지원되는 모든 이미지", + "rawImages": "RAW 이미지", + "selectFilesTitle": "가져올 파일 선택", + "standardImages": "표준 이미지(JPEG, PNG 등)", + "unsupportedFormats": "지원되지 않는 파일 형식이 감지되었습니다: {{formats}}" + }, "fileNaming": "파일 이름 지정", "folderOrganization": "폴더 정리", "organizeByDate": "날짜별 하위 폴더로 정리", @@ -1729,6 +1738,17 @@ } }, "ui": { + "builtInTags": { + "architecture": "건축", + "event": "행사", + "family": "가족", + "food": "음식", + "landscape": "풍경", + "nature": "자연", + "portrait": "인물", + "street": "거리", + "travel": "여행" + }, "bottomBar": { "imagesSelected": "이미지 {{total}}개 중 {{current}}개 선택됨", "tooltips": { @@ -1769,6 +1789,15 @@ "saveAsNewTooltip": "현재 설정을 새 프리셋으로 저장", "savedTooltip": "저장됨!" }, + "filenameVariables": { + "day": "일", + "hour": "시", + "minute": "분", + "month": "월", + "originalFilename": "원본 파일 이름", + "sequence": "순번", + "year": "연도" + }, "filmstrip": { "tooltips": { "color": "색상: {{color}}", diff --git a/src/i18n/locales/pl.json b/src/i18n/locales/pl.json index c7733c2e4c..b2a57737c4 100644 --- a/src/i18n/locales/pl.json +++ b/src/i18n/locales/pl.json @@ -657,7 +657,8 @@ "copy": "Kopiuj", "emptyClickToAdd": "Puste (Kliknij, aby dodać)", "extendedExif": { - "title": "Rozszerzony EXIF" + "title": "Rozszerzony EXIF", + "unknownTiffTag": "Znacznik TIFF ({{id}})" }, "fields": { "author": "Autor", @@ -1287,6 +1288,14 @@ "dateFormatPlaceholder": "np. RRRR/MM-DD", "deleteAfterImport": "Usuń oryginały po pomyślnym imporcie", "deleteWarning": "Pliki zostaną przeniesione do systemowego kosza.", + "fileDialog": { + "allFiles": "Wszystkie pliki", + "allSupportedImages": "Wszystkie obsługiwane obrazy", + "rawImages": "Obrazy RAW", + "selectFilesTitle": "Wybierz pliki do zaimportowania", + "standardImages": "Standardowe obrazy (JPEG, PNG itp.)", + "unsupportedFormats": "Wykryto nieobsługiwane formaty plików: {{formats}}" + }, "fileNaming": "Nazewnictwo plików", "folderOrganization": "Organizacja folderów", "organizeByDate": "Organizuj w podfolderach według daty", @@ -1797,6 +1806,17 @@ } }, "ui": { + "builtInTags": { + "architecture": "Architektura", + "event": "Wydarzenie", + "family": "Rodzina", + "food": "Jedzenie", + "landscape": "Krajobraz", + "nature": "Natura", + "portrait": "Portret", + "street": "Ulica", + "travel": "Podróże" + }, "bottomBar": { "imagesSelected": "Zaznaczono {{current}} z {{total}} obrazów", "tooltips": { @@ -1839,6 +1859,15 @@ "saveAsNewTooltip": "Zapisz obecne ustawienia jako nowy preset", "savedTooltip": "Zapisano!" }, + "filenameVariables": { + "day": "Dzień", + "hour": "Godzina", + "minute": "Minuta", + "month": "Miesiąc", + "originalFilename": "Oryginalna nazwa pliku", + "sequence": "Sekwencja", + "year": "Rok" + }, "filmstrip": { "tooltips": { "color": "Kolor: {{color}}", diff --git a/src/i18n/locales/pt.json b/src/i18n/locales/pt.json index 8617dc4937..053530f9b3 100644 --- a/src/i18n/locales/pt.json +++ b/src/i18n/locales/pt.json @@ -636,7 +636,8 @@ "copy": "Copiar", "emptyClickToAdd": "Vazio (Clique para adicionar)", "extendedExif": { - "title": "EXIF Estendido" + "title": "EXIF Estendido", + "unknownTiffTag": "Etiqueta TIFF ({{id}})" }, "fields": { "author": "Autor", @@ -1260,6 +1261,14 @@ "dateFormatPlaceholder": "ex.: AAAA/MM-DD", "deleteAfterImport": "Excluir originais após importação bem-sucedida", "deleteWarning": "Os arquivos serão movidos para a lixeira do sistema.", + "fileDialog": { + "allFiles": "Todos os arquivos", + "allSupportedImages": "Todas as imagens compatíveis", + "rawImages": "Imagens RAW", + "selectFilesTitle": "Selecionar arquivos para importar", + "standardImages": "Imagens padrão (JPEG, PNG etc.)", + "unsupportedFormats": "Formatos de arquivo não compatíveis detectados: {{formats}}" + }, "fileNaming": "Nomeação de Arquivos", "folderOrganization": "Organização de Pastas", "organizeByDate": "Organizar em subpastas por data", @@ -1764,6 +1773,17 @@ } }, "ui": { + "builtInTags": { + "architecture": "Arquitetura", + "event": "Evento", + "family": "Família", + "food": "Comida", + "landscape": "Paisagem", + "nature": "Natureza", + "portrait": "Retrato", + "street": "Rua", + "travel": "Viagem" + }, "bottomBar": { "imagesSelected": "{{current}} de {{total}} imagens selecionadas", "tooltips": { @@ -1805,6 +1825,15 @@ "saveAsNewTooltip": "Salvar configurações atuais como nova predefinição", "savedTooltip": "Salvo!" }, + "filenameVariables": { + "day": "Dia", + "hour": "Hora", + "minute": "Minuto", + "month": "Mês", + "originalFilename": "Nome do arquivo original", + "sequence": "Sequência", + "year": "Ano" + }, "filmstrip": { "tooltips": { "color": "Cor: {{color}}", diff --git a/src/i18n/locales/ru.json b/src/i18n/locales/ru.json index c925c305a1..a3c34fb68c 100644 --- a/src/i18n/locales/ru.json +++ b/src/i18n/locales/ru.json @@ -657,7 +657,8 @@ "copy": "Копировать", "emptyClickToAdd": "Пусто (нажмите, чтобы добавить)", "extendedExif": { - "title": "Расширенный EXIF" + "title": "Расширенный EXIF", + "unknownTiffTag": "Тег TIFF ({{id}})" }, "fields": { "author": "Автор", @@ -1287,6 +1288,14 @@ "dateFormatPlaceholder": "например, YYYY/MM-DD", "deleteAfterImport": "Удалять исходные файлы после успешного импорта", "deleteWarning": "Файлы будут перемещены в системную корзину.", + "fileDialog": { + "allFiles": "Все файлы", + "allSupportedImages": "Все поддерживаемые изображения", + "rawImages": "Изображения RAW", + "selectFilesTitle": "Выберите файлы для импорта", + "standardImages": "Стандартные изображения (JPEG, PNG и т. д.)", + "unsupportedFormats": "Обнаружены неподдерживаемые форматы файлов: {{formats}}" + }, "fileNaming": "Именование файлов", "folderOrganization": "Структура папок", "organizeByDate": "Распределять по подпапкам на основе даты", @@ -1797,6 +1806,17 @@ } }, "ui": { + "builtInTags": { + "architecture": "Архитектура", + "event": "Событие", + "family": "Семья", + "food": "Еда", + "landscape": "Пейзаж", + "nature": "Природа", + "portrait": "Портрет", + "street": "Улица", + "travel": "Путешествия" + }, "bottomBar": { "imagesSelected": "Выбрано снимков: {{current}} из {{total}}", "tooltips": { @@ -1839,6 +1859,15 @@ "saveAsNewTooltip": "Сохранить текущие параметры как новый пресет экспорта", "savedTooltip": "Сохранено!" }, + "filenameVariables": { + "day": "День", + "hour": "Час", + "minute": "Минута", + "month": "Месяц", + "originalFilename": "Исходное имя файла", + "sequence": "Последовательность", + "year": "Год" + }, "filmstrip": { "tooltips": { "color": "Цвет: {{color}}", diff --git a/src/i18n/locales/zh-CN.json b/src/i18n/locales/zh-CN.json index 31d2b1aeab..35b5f0cfc8 100644 --- a/src/i18n/locales/zh-CN.json +++ b/src/i18n/locales/zh-CN.json @@ -613,7 +613,108 @@ "copy": "复制", "emptyClickToAdd": "空(点击添加)", "extendedExif": { - "title": "扩展 EXIF" + "fields": { + "apertureValue": "光圈值", + "artist": "作者", + "bitsPerSample": "每样本位数", + "bodySerialNumber": "机身序列号", + "brightnessValue": "亮度值", + "cameraSerialNumber": "相机序列号", + "colorSpace": "色彩空间", + "componentsConfiguration": "分量配置", + "compression": "压缩方式", + "contrast": "对比度", + "copyright": "版权", + "createDate": "创建日期", + "customRendered": "自定义图像处理", + "dateTimeOriginal": "拍摄日期", + "digitalZoomRatio": "数码变焦倍率", + "exifVersion": "EXIF 版本", + "exposureBiasValue": "曝光补偿", + "exposureIndex": "曝光指数", + "exposureMode": "曝光模式", + "exposureProgram": "曝光程序", + "fileSource": "文件来源", + "flash": "闪光灯", + "flashpixVersion": "Flashpix 版本", + "focalLength": "焦距", + "focalLengthIn35mmFormat": "等效 35 mm 焦距", + "focalPlaneResolutionUnit": "焦平面分辨率单位", + "focalPlaneXResolution": "焦平面水平分辨率", + "focalPlaneYResolution": "焦平面垂直分辨率", + "gainControl": "增益控制", + "imageDescription": "图像描述", + "imageHeight": "图像高度", + "imageLength": "图像高度", + "imageUniqueId": "图像唯一 ID", + "imageWidth": "图像宽度", + "isoSpeed": "ISO 感光度", + "lensMake": "镜头厂商", + "lensModel": "镜头型号", + "lensSerialNumber": "镜头序列号", + "lensSpecification": "镜头规格", + "lightSource": "光源", + "make": "相机厂商", + "maxApertureValue": "最大光圈值", + "meteringMode": "测光模式", + "model": "相机型号", + "modifyDate": "修改日期", + "offsetTime": "时区偏移", + "offsetTimeDigitized": "数字化时区偏移", + "offsetTimeOriginal": "拍摄时区偏移", + "orientation": "方向", + "photometricInterpretation": "光度解释", + "photographicSensitivity": "感光度", + "pixelXDimension": "像素宽度", + "pixelYDimension": "像素高度", + "planarConfiguration": "平面配置", + "recommendedExposureIndex": "推荐曝光指数", + "resolutionUnit": "分辨率单位", + "rowsPerStrip": "每条带行数", + "saturation": "饱和度", + "samplesPerPixel": "每像素样本数", + "sceneCaptureType": "场景拍摄类型", + "sceneType": "场景类型", + "sensingMethod": "感应方式", + "sensitivityType": "感光度类型", + "sharpness": "锐度", + "shutterSpeedValue": "快门速度值", + "software": "软件", + "stripByteCounts": "条带字节数", + "stripOffsets": "条带偏移量", + "subSecTimeDigitized": "数字化时间亚秒", + "subSecTimeOriginal": "拍摄时间亚秒", + "subjectDistance": "主体距离", + "userComment": "用户备注", + "whiteBalance": "白平衡", + "xResolution": "水平分辨率", + "yResolution": "垂直分辨率" + }, + "title": "扩展 EXIF", + "unknownTiffTag": "TIFF 标签({{id}})", + "values": { + "auto": "自动", + "autoExposure": "自动曝光", + "chunky": "交错排列", + "digitalStillCamera": "数码相机", + "directlyPhotographed": "直接拍摄", + "flashDidNotFire": "闪光灯未闪光", + "flashFiredReturnDetected": "闪光灯已闪光,检测到回光", + "flashFiredReturnNotDetected": "闪光灯已闪光,未检测到回光", + "flashFiredReturnNotDetectedForced": "闪光灯已闪光,未检测到回光,强制闪光", + "landscape": "风光", + "manual": "手动", + "manualExposure": "手动曝光", + "noFlash": "未闪光", + "normal": "标准", + "normalProcess": "标准处理", + "patternMetering": "多区测光", + "portrait": "人像", + "standard": "标准", + "topLeft": "正常(左上)", + "uncompressed": "未压缩", + "unknown": "未知" + } }, "fields": { "author": "作者", @@ -1037,7 +1138,7 @@ "types": { "all": "整个图像", "brush": "画笔", - "clone": "克隆", + "clone": "仿制", "color": "颜色", "depth": "深度", "flow": "流线", @@ -1231,6 +1332,14 @@ "dateFormatPlaceholder": "例如,YYYY/MM-DD", "deleteAfterImport": "成功导入后删除原始文件", "deleteWarning": "文件将被移至系统回收站。", + "fileDialog": { + "allFiles": "所有文件", + "allSupportedImages": "所有支持的图像", + "rawImages": "RAW 图像", + "selectFilesTitle": "选择要导入的文件", + "standardImages": "标准图像(JPEG、PNG 等)", + "unsupportedFormats": "检测到不支持的文件格式:{{formats}}" + }, "fileNaming": "文件命名", "folderOrganization": "文件夹组织", "organizeByDate": "按日期组织到子文件夹", @@ -1729,6 +1838,17 @@ } }, "ui": { + "builtInTags": { + "architecture": "建筑", + "event": "活动", + "family": "家庭", + "food": "美食", + "landscape": "风光", + "nature": "自然", + "portrait": "人像", + "street": "街头", + "travel": "旅行" + }, "bottomBar": { "imagesSelected": "已选择 {{current}} / {{total}} 张图像", "tooltips": { @@ -1769,6 +1889,15 @@ "saveAsNewTooltip": "将当前设置保存为新预设", "savedTooltip": "已保存!" }, + "filenameVariables": { + "day": "日", + "hour": "时", + "minute": "分", + "month": "月", + "originalFilename": "原始文件名", + "sequence": "序号", + "year": "年" + }, "filmstrip": { "tooltips": { "color": "颜色:{{color}}", diff --git a/src/i18n/locales/zh-TW.json b/src/i18n/locales/zh-TW.json index a2a09ca1cb..cfdffc9c82 100644 --- a/src/i18n/locales/zh-TW.json +++ b/src/i18n/locales/zh-TW.json @@ -613,7 +613,108 @@ "copy": "複製", "emptyClickToAdd": "空(點選新增)", "extendedExif": { - "title": "擴充 EXIF" + "fields": { + "apertureValue": "光圈值", + "artist": "作者", + "bitsPerSample": "每樣本位元數", + "bodySerialNumber": "機身序號", + "brightnessValue": "亮度值", + "cameraSerialNumber": "相機序號", + "colorSpace": "色彩空間", + "componentsConfiguration": "分量設定", + "compression": "壓縮方式", + "contrast": "對比度", + "copyright": "版權", + "createDate": "建立日期", + "customRendered": "自訂影像處理", + "dateTimeOriginal": "拍攝日期", + "digitalZoomRatio": "數位變焦倍率", + "exifVersion": "EXIF 版本", + "exposureBiasValue": "曝光補償", + "exposureIndex": "曝光指數", + "exposureMode": "曝光模式", + "exposureProgram": "曝光程式", + "fileSource": "檔案來源", + "flash": "閃光燈", + "flashpixVersion": "Flashpix 版本", + "focalLength": "焦距", + "focalLengthIn35mmFormat": "等效 35 mm 焦距", + "focalPlaneResolutionUnit": "焦平面解析度單位", + "focalPlaneXResolution": "焦平面水平解析度", + "focalPlaneYResolution": "焦平面垂直解析度", + "gainControl": "增益控制", + "imageDescription": "影像描述", + "imageHeight": "影像高度", + "imageLength": "影像高度", + "imageUniqueId": "影像唯一 ID", + "imageWidth": "影像寬度", + "isoSpeed": "ISO 感光度", + "lensMake": "鏡頭製造商", + "lensModel": "鏡頭型號", + "lensSerialNumber": "鏡頭序號", + "lensSpecification": "鏡頭規格", + "lightSource": "光源", + "make": "相機製造商", + "maxApertureValue": "最大光圈值", + "meteringMode": "測光模式", + "model": "相機型號", + "modifyDate": "修改日期", + "offsetTime": "時區偏移", + "offsetTimeDigitized": "數位化時區偏移", + "offsetTimeOriginal": "拍攝時區偏移", + "orientation": "方向", + "photometricInterpretation": "光度解釋", + "photographicSensitivity": "感光度", + "pixelXDimension": "像素寬度", + "pixelYDimension": "像素高度", + "planarConfiguration": "平面設定", + "recommendedExposureIndex": "建議曝光指數", + "resolutionUnit": "解析度單位", + "rowsPerStrip": "每條帶列數", + "saturation": "飽和度", + "samplesPerPixel": "每像素樣本數", + "sceneCaptureType": "場景拍攝類型", + "sceneType": "場景類型", + "sensingMethod": "感測方式", + "sensitivityType": "感光度類型", + "sharpness": "銳利度", + "shutterSpeedValue": "快門速度值", + "software": "軟體", + "stripByteCounts": "條帶位元組數", + "stripOffsets": "條帶偏移量", + "subSecTimeDigitized": "數位化時間亞秒", + "subSecTimeOriginal": "拍攝時間亞秒", + "subjectDistance": "主體距離", + "userComment": "使用者備註", + "whiteBalance": "白平衡", + "xResolution": "水平解析度", + "yResolution": "垂直解析度" + }, + "title": "擴充 EXIF", + "unknownTiffTag": "TIFF 標籤({{id}})", + "values": { + "auto": "自動", + "autoExposure": "自動曝光", + "chunky": "交錯排列", + "digitalStillCamera": "數位相機", + "directlyPhotographed": "直接拍攝", + "flashDidNotFire": "閃光燈未閃光", + "flashFiredReturnDetected": "閃光燈已閃光,偵測到回光", + "flashFiredReturnNotDetected": "閃光燈已閃光,未偵測到回光", + "flashFiredReturnNotDetectedForced": "閃光燈已閃光,未偵測到回光,強制閃光", + "landscape": "風景", + "manual": "手動", + "manualExposure": "手動曝光", + "noFlash": "未閃光", + "normal": "標準", + "normalProcess": "標準處理", + "patternMetering": "多區測光", + "portrait": "人像", + "standard": "標準", + "topLeft": "正常(左上)", + "uncompressed": "未壓縮", + "unknown": "未知" + } }, "fields": { "author": "作者", @@ -1231,6 +1332,14 @@ "dateFormatPlaceholder": "例如,YYYY/MM-DD", "deleteAfterImport": "成功匯入後刪除原始檔案", "deleteWarning": "檔案將被移至垃圾桶。", + "fileDialog": { + "allFiles": "所有檔案", + "allSupportedImages": "所有支援的影像", + "rawImages": "RAW 影像", + "selectFilesTitle": "選擇要匯入的檔案", + "standardImages": "標準影像(JPEG、PNG 等)", + "unsupportedFormats": "偵測到不支援的檔案格式:{{formats}}" + }, "fileNaming": "檔案命名", "folderOrganization": "資料夾組織", "organizeByDate": "按日期組織到子資料夾", @@ -1729,6 +1838,17 @@ } }, "ui": { + "builtInTags": { + "architecture": "建築", + "event": "活動", + "family": "家庭", + "food": "美食", + "landscape": "風景", + "nature": "自然", + "portrait": "人像", + "street": "街頭", + "travel": "旅行" + }, "bottomBar": { "imagesSelected": "已選擇 {{current}} / {{total}} 張影像", "tooltips": { @@ -1769,6 +1889,15 @@ "saveAsNewTooltip": "將當前設定儲存為新預設", "savedTooltip": "已儲存!" }, + "filenameVariables": { + "day": "日", + "hour": "時", + "minute": "分", + "month": "月", + "originalFilename": "原始檔名", + "sequence": "序號", + "year": "年" + }, "filmstrip": { "tooltips": { "color": "顏色:{{color}}", diff --git a/src/i18n/translateBuiltInTag.ts b/src/i18n/translateBuiltInTag.ts new file mode 100644 index 0000000000..0e3e73bb0c --- /dev/null +++ b/src/i18n/translateBuiltInTag.ts @@ -0,0 +1,19 @@ +import i18n from 'i18next'; + +const BUILT_IN_TAG_KEYS = { + architecture: 'ui.builtInTags.architecture', + event: 'ui.builtInTags.event', + family: 'ui.builtInTags.family', + food: 'ui.builtInTags.food', + landscape: 'ui.builtInTags.landscape', + nature: 'ui.builtInTags.nature', + portrait: 'ui.builtInTags.portrait', + street: 'ui.builtInTags.street', + travel: 'ui.builtInTags.travel', +} as const; + +export function translateBuiltInTag(tag: string): string { + const normalizedTag = tag.trim().toLowerCase() as keyof typeof BUILT_IN_TAG_KEYS; + const translationKey = BUILT_IN_TAG_KEYS[normalizedTag]; + return translationKey ? String(i18n.t(translationKey)) : tag; +}