Compare commits
2 Commits
7c44af8f7c
...
0c71399867
Author | SHA1 | Date |
---|---|---|
|
0c71399867 | |
|
b2d96e466e |
|
@ -123,3 +123,5 @@ docs/.*
|
||||||
.vscode/launch.json
|
.vscode/launch.json
|
||||||
devtools_options.yaml
|
devtools_options.yaml
|
||||||
test/features/*_test.dart
|
test/features/*_test.dart
|
||||||
|
**/app_localizations*.dart
|
||||||
|
.env
|
||||||
|
|
|
@ -1,6 +1,12 @@
|
||||||
{
|
{
|
||||||
"recommendations": [
|
"recommendations": [
|
||||||
"yzhang.markdown-all-in-one",
|
"yzhang.markdown-all-in-one",
|
||||||
"alexkrechik.cucumberautocomplete"
|
"alexkrechik.cucumberautocomplete",
|
||||||
|
"google.arb-editor",
|
||||||
|
"dart-code.flutter",
|
||||||
|
"lsaudon.l10nization", // quick translation gen
|
||||||
|
"oke331.flutter-l10n-helper", // show arb string
|
||||||
|
"gabbygreat.flutter-l10n-checker", // detect hard-coded strings
|
||||||
|
// "joaopinacio.translate-me"
|
||||||
]
|
]
|
||||||
}
|
}
|
|
@ -10,6 +10,7 @@ checkout [`docs/FRs.md`](docs/FRs.md)
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# flutter clean
|
# flutter clean
|
||||||
|
# arb_translate
|
||||||
flutter pub get
|
flutter pub get
|
||||||
# generate gherkin test
|
# generate gherkin test
|
||||||
flutter pub run build_runner build --delete-conflicting-outputs
|
flutter pub run build_runner build --delete-conflicting-outputs
|
||||||
|
|
|
@ -3,4 +3,3 @@ template-arb-file: app_en.arb
|
||||||
output-class: AppLocalizations
|
output-class: AppLocalizations
|
||||||
output-localization-file: app_localizations.dart
|
output-localization-file: app_localizations.dart
|
||||||
nullable-getter: false
|
nullable-getter: false
|
||||||
untranslated-messages-file: build/l10n_missing.txt
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
|
import 'package:flutter_localized_locales/flutter_localized_locales.dart';
|
||||||
import 'package:pdf_signature/l10n/app_localizations.dart';
|
import 'package:pdf_signature/l10n/app_localizations.dart';
|
||||||
import 'package:pdf_signature/ui/features/pdf/widgets/pdf_screen.dart';
|
import 'package:pdf_signature/ui/features/pdf/widgets/pdf_screen.dart';
|
||||||
import 'ui/features/preferences/providers.dart';
|
import 'ui/features/preferences/providers.dart';
|
||||||
|
@ -55,7 +56,10 @@ class MyApp extends StatelessWidget {
|
||||||
themeMode: themeMode,
|
themeMode: themeMode,
|
||||||
locale: appLocale,
|
locale: appLocale,
|
||||||
supportedLocales: AppLocalizations.supportedLocales,
|
supportedLocales: AppLocalizations.supportedLocales,
|
||||||
localizationsDelegates: AppLocalizations.localizationsDelegates,
|
localizationsDelegates: [
|
||||||
|
...AppLocalizations.localizationsDelegates,
|
||||||
|
LocaleNamesLocalizationsDelegate(),
|
||||||
|
],
|
||||||
home: const PdfSignatureHomePage(),
|
home: const PdfSignatureHomePage(),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
|
@ -49,9 +49,7 @@ class PdfState {
|
||||||
signedPage: signedPage ?? this.signedPage,
|
signedPage: signedPage ?? this.signedPage,
|
||||||
placementsByPage: placementsByPage ?? this.placementsByPage,
|
placementsByPage: placementsByPage ?? this.placementsByPage,
|
||||||
selectedPlacementIndex:
|
selectedPlacementIndex:
|
||||||
selectedPlacementIndex == null
|
selectedPlacementIndex ?? this.selectedPlacementIndex,
|
||||||
? this.selectedPlacementIndex
|
|
||||||
: selectedPlacementIndex,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
{
|
||||||
|
"appTitle": "PDF-Signatur",
|
||||||
|
"backgroundRemoval": "Hintergrund entfernen",
|
||||||
|
"brightness": "Helligkeit",
|
||||||
|
"clear": "Löschen",
|
||||||
|
"confirm": "Bestätigen",
|
||||||
|
"contrast": "Kontrast",
|
||||||
|
"createNewSignature": "Neue Signatur erstellen",
|
||||||
|
"delete": "Löschen",
|
||||||
|
"downloadStarted": "Download gestartet",
|
||||||
|
"dpi": "DPI:",
|
||||||
|
"drawSignature": "Signatur zeichnen",
|
||||||
|
"errorWithMessage": "Fehler: {message}",
|
||||||
|
"exportingPleaseWait": "Exportiere… Bitte warten",
|
||||||
|
"failedToGeneratePdf": "PDF konnte nicht generiert werden",
|
||||||
|
"failedToSavePdf": "PDF konnte nicht gespeichert werden",
|
||||||
|
"goTo": "Gehe zu:",
|
||||||
|
"invalidOrUnsupportedFile": "Ungültige oder nicht unterstützte Datei",
|
||||||
|
"language": "Sprache",
|
||||||
|
"loadSignatureFromFile": "Signatur aus Datei laden",
|
||||||
|
"lockAspectRatio": "Seitenverhältnis sperren",
|
||||||
|
"longPressOrRightClickTheSignatureToConfirmOrDelete": "Drücken Sie lange oder klicken Sie mit der rechten Maustaste auf die Signatur, um sie zu bestätigen oder zu löschen.",
|
||||||
|
"next": "Weiter",
|
||||||
|
"noPdfLoaded": "Keine PDF-Datei geladen",
|
||||||
|
"nothingToSaveYet": "Noch nichts zu speichern",
|
||||||
|
"openPdf": "PDF öffnen...",
|
||||||
|
"pageInfo": "Seite {current}/{total}",
|
||||||
|
"prev": "Vorherige",
|
||||||
|
"resetToDefaults": "Auf Standardwerte zurücksetzen",
|
||||||
|
"savedWithPath": "Gespeichert: {path}",
|
||||||
|
"saveSignedPdf": "Signiertes PDF speichern",
|
||||||
|
"settings": "Einstellungen",
|
||||||
|
"signature": "Signatur",
|
||||||
|
"theme": "Design",
|
||||||
|
"themeDark": "Dunkel",
|
||||||
|
"themeLight": "Hell",
|
||||||
|
"themeSystem": "System",
|
||||||
|
"undo": "Rückgängig"
|
||||||
|
}
|
|
@ -1,59 +1,101 @@
|
||||||
{
|
{
|
||||||
"@@locale": "en",
|
"@@locale": "en",
|
||||||
"appTitle": "PDF Signature",
|
"appTitle": "PDF Signature",
|
||||||
|
"@appTitle": {},
|
||||||
|
"backgroundRemoval": "Background removal",
|
||||||
|
"@backgroundRemoval": {},
|
||||||
|
"brightness": "Brightness",
|
||||||
|
"@brightness": {},
|
||||||
|
"clear": "Clear",
|
||||||
|
"@clear": {},
|
||||||
|
"confirm": "Confirm",
|
||||||
|
"@confirm": {},
|
||||||
|
"contrast": "Contrast",
|
||||||
|
"@contrast": {},
|
||||||
|
"createNewSignature": "Create new signature",
|
||||||
|
"@createNewSignature": {},
|
||||||
|
"delete": "Delete",
|
||||||
|
"@delete": {},
|
||||||
|
"downloadStarted": "Download started",
|
||||||
|
"@downloadStarted": {},
|
||||||
|
"dpi": "DPI:",
|
||||||
|
"@dpi": {},
|
||||||
|
"drawSignature": "Draw Signature",
|
||||||
|
"@drawSignature": {},
|
||||||
"errorWithMessage": "Error: {message}",
|
"errorWithMessage": "Error: {message}",
|
||||||
"@errorWithMessage": {
|
"@errorWithMessage": {
|
||||||
"description": "Generic error text with message",
|
"description": "Generic error text with message",
|
||||||
"placeholders": {"message": {"type": "String"}}
|
"placeholders": {
|
||||||
|
"message": {
|
||||||
|
"type": "String"
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
"exportingPleaseWait": "Exporting... Please wait",
|
||||||
"settings": "Settings",
|
"@exportingPleaseWait": {},
|
||||||
"theme": "Theme",
|
"failedToGeneratePdf": "Failed to generate PDF",
|
||||||
"themeLight": "Light",
|
"@failedToGeneratePdf": {},
|
||||||
"themeDark": "Dark",
|
"failedToSavePdf": "Failed to save PDF",
|
||||||
"themeSystem": "System",
|
"@failedToSavePdf": {},
|
||||||
|
"goTo": "Go to:",
|
||||||
|
"@goTo": {},
|
||||||
|
"invalidOrUnsupportedFile": "Invalid or unsupported file",
|
||||||
|
"@invalidOrUnsupportedFile": {},
|
||||||
"language": "Language",
|
"language": "Language",
|
||||||
"languageEnglish": "English",
|
"@language": {},
|
||||||
"languageChineseTraditional": "Traditional Chinese",
|
"loadSignatureFromFile": "Load Signature from file",
|
||||||
"languageSpanish": "Spanish",
|
"@loadSignatureFromFile": {},
|
||||||
"resetToDefaults": "Reset to defaults",
|
"lockAspectRatio": "Lock aspect ratio",
|
||||||
|
"@lockAspectRatio": {},
|
||||||
"openPdf": "Open PDF...",
|
"longPressOrRightClickTheSignatureToConfirmOrDelete": "Long-press or right-click the signature to Confirm or Delete.",
|
||||||
"prev": "Prev",
|
"@longPressOrRightClickTheSignatureToConfirmOrDelete": {},
|
||||||
"next": "Next",
|
"next": "Next",
|
||||||
|
"@next": {},
|
||||||
|
"noPdfLoaded": "No PDF loaded",
|
||||||
|
"@noPdfLoaded": {},
|
||||||
|
"nothingToSaveYet": "Nothing to save yet",
|
||||||
|
"@nothingToSaveYet": {},
|
||||||
|
"openPdf": "Open PDF...",
|
||||||
|
"@openPdf": {},
|
||||||
"pageInfo": "Page {current}/{total}",
|
"pageInfo": "Page {current}/{total}",
|
||||||
"@pageInfo": {
|
"@pageInfo": {
|
||||||
"description": "Label showing current page and total",
|
"description": "Label showing current page and total",
|
||||||
"placeholders": {
|
"placeholders": {
|
||||||
"current": {"type": "int"},
|
"current": {
|
||||||
"total": {"type": "int"}
|
"type": "int"
|
||||||
|
},
|
||||||
|
"total": {
|
||||||
|
"type": "int"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"goTo": "Go to:",
|
"prev": "Prev",
|
||||||
"dpi": "DPI:",
|
"@prev": {},
|
||||||
"saveSignedPdf": "Save Signed PDF",
|
"resetToDefaults": "Reset to defaults",
|
||||||
"loadSignatureFromFile": "Load Signature from file",
|
"@resetToDefaults": {},
|
||||||
"drawSignature": "Draw Signature",
|
|
||||||
"noPdfLoaded": "No PDF loaded",
|
|
||||||
"signature": "Signature",
|
|
||||||
"lockAspectRatio": "Lock aspect ratio",
|
|
||||||
"backgroundRemoval": "Background removal",
|
|
||||||
"contrast": "Contrast",
|
|
||||||
"brightness": "Brightness",
|
|
||||||
"exportingPleaseWait": "Exporting... Please wait",
|
|
||||||
|
|
||||||
"nothingToSaveYet": "Nothing to save yet",
|
|
||||||
"savedWithPath": "Saved: {path}",
|
"savedWithPath": "Saved: {path}",
|
||||||
"@savedWithPath": {
|
"@savedWithPath": {
|
||||||
"description": "Snackbar text showing where file saved",
|
"description": "Snackbar text showing where file saved",
|
||||||
"placeholders": {"path": {"type": "String"}}
|
"placeholders": {
|
||||||
},
|
"path": {
|
||||||
"failedToSavePdf": "Failed to save PDF",
|
"type": "String"
|
||||||
"downloadStarted": "Download started",
|
}
|
||||||
"failedToGeneratePdf": "Failed to generate PDF",
|
}
|
||||||
"invalidOrUnsupportedFile": "Invalid or unsupported file",
|
},
|
||||||
|
"saveSignedPdf": "Save Signed PDF",
|
||||||
"confirm": "Confirm",
|
"@saveSignedPdf": {},
|
||||||
"undo": "Undo",
|
"settings": "Settings",
|
||||||
"clear": "Clear"
|
"@settings": {},
|
||||||
|
"signature": "Signature",
|
||||||
|
"@signature": {},
|
||||||
|
"theme": "Theme",
|
||||||
|
"@theme": {},
|
||||||
|
"themeDark": "Dark",
|
||||||
|
"@themeDark": {},
|
||||||
|
"themeLight": "Light",
|
||||||
|
"@themeLight": {},
|
||||||
|
"themeSystem": "System",
|
||||||
|
"@themeSystem": {},
|
||||||
|
"undo": "Undo",
|
||||||
|
"@undo": {}
|
||||||
}
|
}
|
|
@ -1,44 +1,39 @@
|
||||||
{
|
{
|
||||||
"@@locale": "es",
|
|
||||||
"appTitle": "Firma PDF",
|
"appTitle": "Firma PDF",
|
||||||
"errorWithMessage": "Error: {message}",
|
"backgroundRemoval": "Eliminar fondo",
|
||||||
|
|
||||||
"settings": "Ajustes",
|
|
||||||
"theme": "Tema",
|
|
||||||
"themeLight": "Claro",
|
|
||||||
"themeDark": "Oscuro",
|
|
||||||
"themeSystem": "Del sistema",
|
|
||||||
"language": "Idioma",
|
|
||||||
"languageEnglish": "Inglés",
|
|
||||||
"languageChineseTraditional": "Chino tradicional",
|
|
||||||
"languageSpanish": "Español",
|
|
||||||
"resetToDefaults": "Restablecer valores",
|
|
||||||
|
|
||||||
"openPdf": "Abrir PDF…",
|
|
||||||
"prev": "Anterior",
|
|
||||||
"next": "Siguiente",
|
|
||||||
"pageInfo": "Página {current}/{total}",
|
|
||||||
"goTo": "Ir a:",
|
|
||||||
"dpi": "DPI:",
|
|
||||||
"saveSignedPdf": "Guardar PDF firmado",
|
|
||||||
"loadSignatureFromFile": "Cargar firma desde archivo",
|
|
||||||
"drawSignature": "Dibujar firma",
|
|
||||||
"noPdfLoaded": "No hay PDF cargado",
|
|
||||||
"signature": "Firma",
|
|
||||||
"lockAspectRatio": "Bloquear relación de aspecto",
|
|
||||||
"backgroundRemoval": "Eliminación de fondo",
|
|
||||||
"contrast": "Contraste",
|
|
||||||
"brightness": "Brillo",
|
"brightness": "Brillo",
|
||||||
"exportingPleaseWait": "Exportando... Por favor espera",
|
"clear": "Limpiar",
|
||||||
|
|
||||||
"nothingToSaveYet": "Nada que guardar todavía",
|
|
||||||
"savedWithPath": "Guardado: {path}",
|
|
||||||
"failedToSavePdf": "Error al guardar el PDF",
|
|
||||||
"downloadStarted": "Descarga iniciada",
|
|
||||||
"failedToGeneratePdf": "Error al generar el PDF",
|
|
||||||
"invalidOrUnsupportedFile": "Archivo no válido o no compatible",
|
|
||||||
|
|
||||||
"confirm": "Confirmar",
|
"confirm": "Confirmar",
|
||||||
"undo": "Deshacer",
|
"contrast": "Contraste",
|
||||||
"clear": "Limpiar"
|
"createNewSignature": "Crear nueva firma",
|
||||||
|
"delete": "Eliminar",
|
||||||
|
"downloadStarted": "Descarga iniciada",
|
||||||
|
"dpi": "DPI:",
|
||||||
|
"drawSignature": "Dibujar firma",
|
||||||
|
"errorWithMessage": "Error: {message}",
|
||||||
|
"exportingPleaseWait": "Exportando... Por favor, espere",
|
||||||
|
"failedToGeneratePdf": "No se pudo generar el PDF",
|
||||||
|
"failedToSavePdf": "No se pudo guardar el PDF",
|
||||||
|
"goTo": "Ir a:",
|
||||||
|
"invalidOrUnsupportedFile": "Archivo inválido o no compatible",
|
||||||
|
"language": "Idioma",
|
||||||
|
"loadSignatureFromFile": "Cargar firma desde archivo",
|
||||||
|
"lockAspectRatio": "Bloquear relación de aspecto",
|
||||||
|
"longPressOrRightClickTheSignatureToConfirmOrDelete": "Pulse prolongadamente o haga clic derecho en la firma para confirmar o eliminar.",
|
||||||
|
"next": "Siguiente",
|
||||||
|
"noPdfLoaded": "No se ha cargado ningún PDF",
|
||||||
|
"nothingToSaveYet": "Aún no hay nada que guardar",
|
||||||
|
"openPdf": "Abrir PDF...",
|
||||||
|
"pageInfo": "Página {current}/{total}",
|
||||||
|
"prev": "Anterior",
|
||||||
|
"resetToDefaults": "Restablecer valores predeterminados",
|
||||||
|
"savedWithPath": "Guardado: {path}",
|
||||||
|
"saveSignedPdf": "Guardar PDF firmado",
|
||||||
|
"settings": "Ajustes",
|
||||||
|
"signature": "Firma",
|
||||||
|
"theme": "Tema",
|
||||||
|
"themeDark": "Oscuro",
|
||||||
|
"themeLight": "Claro",
|
||||||
|
"themeSystem": "Sistema",
|
||||||
|
"undo": "Deshacer"
|
||||||
}
|
}
|
|
@ -0,0 +1,39 @@
|
||||||
|
{
|
||||||
|
"appTitle": "Signature PDF",
|
||||||
|
"backgroundRemoval": "Suppression de l'arrière-plan",
|
||||||
|
"brightness": "Luminosité",
|
||||||
|
"clear": "Effacer",
|
||||||
|
"confirm": "Confirmer",
|
||||||
|
"contrast": "Contraste",
|
||||||
|
"createNewSignature": "Créer une nouvelle signature",
|
||||||
|
"delete": "Supprimer",
|
||||||
|
"downloadStarted": "Téléchargement commencé",
|
||||||
|
"dpi": "DPI :",
|
||||||
|
"drawSignature": "Dessiner une signature",
|
||||||
|
"errorWithMessage": "Erreur : {message}",
|
||||||
|
"exportingPleaseWait": "Exportation… Veuillez patienter",
|
||||||
|
"failedToGeneratePdf": "Échec de la génération du PDF",
|
||||||
|
"failedToSavePdf": "Échec de l'enregistrement du PDF",
|
||||||
|
"goTo": "Aller à :",
|
||||||
|
"invalidOrUnsupportedFile": "Fichier invalide ou non pris en charge",
|
||||||
|
"language": "Langue",
|
||||||
|
"loadSignatureFromFile": "Charger une signature depuis un fichier",
|
||||||
|
"lockAspectRatio": "Verrouiller le ratio largeur/hauteur",
|
||||||
|
"longPressOrRightClickTheSignatureToConfirmOrDelete": "Appuyez longuement ou cliquez droit sur la signature pour la confirmer ou la supprimer.",
|
||||||
|
"next": "Suivant",
|
||||||
|
"noPdfLoaded": "Aucun PDF chargé",
|
||||||
|
"nothingToSaveYet": "Rien à enregistrer pour le moment",
|
||||||
|
"openPdf": "Ouvrir un PDF...",
|
||||||
|
"pageInfo": "Page {current}/{total}",
|
||||||
|
"prev": "Précédent",
|
||||||
|
"resetToDefaults": "Rétablir les valeurs par défaut",
|
||||||
|
"savedWithPath": "Enregistré : {path}",
|
||||||
|
"saveSignedPdf": "Enregistrer le PDF signé",
|
||||||
|
"settings": "Paramètres",
|
||||||
|
"signature": "Signature",
|
||||||
|
"theme": "Thème",
|
||||||
|
"themeDark": "Sombre",
|
||||||
|
"themeLight": "Clair",
|
||||||
|
"themeSystem": "Système",
|
||||||
|
"undo": "Annuler"
|
||||||
|
}
|
|
@ -0,0 +1,39 @@
|
||||||
|
{
|
||||||
|
"appTitle": "PDF署名",
|
||||||
|
"backgroundRemoval": "背景除去",
|
||||||
|
"brightness": "明るさ",
|
||||||
|
"clear": "クリア",
|
||||||
|
"confirm": "確認",
|
||||||
|
"contrast": "コントラスト",
|
||||||
|
"createNewSignature": "新しい署名を作成",
|
||||||
|
"delete": "削除",
|
||||||
|
"downloadStarted": "ダウンロード開始",
|
||||||
|
"dpi": "DPI:",
|
||||||
|
"drawSignature": "署名をかく",
|
||||||
|
"errorWithMessage": "エラー:{message}",
|
||||||
|
"exportingPleaseWait": "エクスポート中…お待ちください",
|
||||||
|
"failedToGeneratePdf": "PDFの生成に失敗しました",
|
||||||
|
"failedToSavePdf": "PDFの保存に失敗しました",
|
||||||
|
"goTo": "移動:",
|
||||||
|
"invalidOrUnsupportedFile": "無効なファイルまたはサポートされていないファイル",
|
||||||
|
"language": "言語",
|
||||||
|
"loadSignatureFromFile": "ファイルから署名を読み込む",
|
||||||
|
"lockAspectRatio": "アスペクト比をロック",
|
||||||
|
"longPressOrRightClickTheSignatureToConfirmOrDelete": "署名を長押しまたは右クリックして、確認または削除します。",
|
||||||
|
"next": "次へ",
|
||||||
|
"noPdfLoaded": "PDFが読み込まれていません",
|
||||||
|
"nothingToSaveYet": "まだ保存するものがありません",
|
||||||
|
"openPdf": "PDFを開く…",
|
||||||
|
"pageInfo": "ページ {current}/{total}",
|
||||||
|
"prev": "前へ",
|
||||||
|
"resetToDefaults": "デフォルトに戻す",
|
||||||
|
"savedWithPath": "保存しました:{path}",
|
||||||
|
"saveSignedPdf": "署名済みPDFを保存",
|
||||||
|
"settings": "設定",
|
||||||
|
"signature": "署名",
|
||||||
|
"theme": "テーマ",
|
||||||
|
"themeDark": "ダーク",
|
||||||
|
"themeLight": "ライト",
|
||||||
|
"themeSystem": "システム",
|
||||||
|
"undo": "元に戻す"
|
||||||
|
}
|
|
@ -0,0 +1,39 @@
|
||||||
|
{
|
||||||
|
"appTitle": "PDF 서명",
|
||||||
|
"backgroundRemoval": "배경 제거",
|
||||||
|
"brightness": "밝기",
|
||||||
|
"clear": "지우기",
|
||||||
|
"confirm": "확인",
|
||||||
|
"contrast": "대비",
|
||||||
|
"createNewSignature": "새 서명 만들기",
|
||||||
|
"delete": "삭제",
|
||||||
|
"downloadStarted": "다운로드 시작됨",
|
||||||
|
"dpi": "DPI:",
|
||||||
|
"drawSignature": "서명 그리기",
|
||||||
|
"errorWithMessage": "오류: {message}",
|
||||||
|
"exportingPleaseWait": "내보내는 중... 잠시 기다려주세요",
|
||||||
|
"failedToGeneratePdf": "PDF 생성 실패",
|
||||||
|
"failedToSavePdf": "PDF 저장 실패",
|
||||||
|
"goTo": "이동:",
|
||||||
|
"invalidOrUnsupportedFile": "잘못된 파일이거나 지원되지 않는 파일입니다.",
|
||||||
|
"language": "언어",
|
||||||
|
"loadSignatureFromFile": "파일에서 서명 불러오기",
|
||||||
|
"lockAspectRatio": "종횡비 고정",
|
||||||
|
"longPressOrRightClickTheSignatureToConfirmOrDelete": "서명을 길게 누르거나 마우스 오른쪽 버튼을 클릭하여 확인하거나 삭제합니다.",
|
||||||
|
"next": "다음",
|
||||||
|
"noPdfLoaded": "로드된 PDF 없음",
|
||||||
|
"nothingToSaveYet": "아직 저장할 내용이 없습니다.",
|
||||||
|
"openPdf": "PDF 열기...",
|
||||||
|
"pageInfo": "{current}/{total} 페이지",
|
||||||
|
"prev": "이전",
|
||||||
|
"resetToDefaults": "기본값으로 재설정",
|
||||||
|
"savedWithPath": "{path}에 저장됨",
|
||||||
|
"saveSignedPdf": "서명된 PDF 저장",
|
||||||
|
"settings": "설정",
|
||||||
|
"signature": "서명",
|
||||||
|
"theme": "테마",
|
||||||
|
"themeDark": "다크",
|
||||||
|
"themeLight": "라이트",
|
||||||
|
"themeSystem": "시스템",
|
||||||
|
"undo": "실행 취소"
|
||||||
|
}
|
|
@ -1,373 +0,0 @@
|
||||||
import 'dart:async';
|
|
||||||
|
|
||||||
import 'package:flutter/foundation.dart';
|
|
||||||
import 'package:flutter/widgets.dart';
|
|
||||||
import 'package:flutter_localizations/flutter_localizations.dart';
|
|
||||||
import 'package:intl/intl.dart' as intl;
|
|
||||||
|
|
||||||
import 'app_localizations_en.dart';
|
|
||||||
import 'app_localizations_es.dart';
|
|
||||||
import 'app_localizations_zh.dart';
|
|
||||||
|
|
||||||
// ignore_for_file: type=lint
|
|
||||||
|
|
||||||
/// Callers can lookup localized strings with an instance of AppLocalizations
|
|
||||||
/// returned by `AppLocalizations.of(context)`.
|
|
||||||
///
|
|
||||||
/// Applications need to include `AppLocalizations.delegate()` in their app's
|
|
||||||
/// `localizationDelegates` list, and the locales they support in the app's
|
|
||||||
/// `supportedLocales` list. For example:
|
|
||||||
///
|
|
||||||
/// ```dart
|
|
||||||
/// import 'l10n/app_localizations.dart';
|
|
||||||
///
|
|
||||||
/// return MaterialApp(
|
|
||||||
/// localizationsDelegates: AppLocalizations.localizationsDelegates,
|
|
||||||
/// supportedLocales: AppLocalizations.supportedLocales,
|
|
||||||
/// home: MyApplicationHome(),
|
|
||||||
/// );
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// ## Update pubspec.yaml
|
|
||||||
///
|
|
||||||
/// Please make sure to update your pubspec.yaml to include the following
|
|
||||||
/// packages:
|
|
||||||
///
|
|
||||||
/// ```yaml
|
|
||||||
/// dependencies:
|
|
||||||
/// # Internationalization support.
|
|
||||||
/// flutter_localizations:
|
|
||||||
/// sdk: flutter
|
|
||||||
/// intl: any # Use the pinned version from flutter_localizations
|
|
||||||
///
|
|
||||||
/// # Rest of dependencies
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// ## iOS Applications
|
|
||||||
///
|
|
||||||
/// iOS applications define key application metadata, including supported
|
|
||||||
/// locales, in an Info.plist file that is built into the application bundle.
|
|
||||||
/// To configure the locales supported by your app, you’ll need to edit this
|
|
||||||
/// file.
|
|
||||||
///
|
|
||||||
/// First, open your project’s ios/Runner.xcworkspace Xcode workspace file.
|
|
||||||
/// Then, in the Project Navigator, open the Info.plist file under the Runner
|
|
||||||
/// project’s Runner folder.
|
|
||||||
///
|
|
||||||
/// Next, select the Information Property List item, select Add Item from the
|
|
||||||
/// Editor menu, then select Localizations from the pop-up menu.
|
|
||||||
///
|
|
||||||
/// Select and expand the newly-created Localizations item then, for each
|
|
||||||
/// locale your application supports, add a new item and select the locale
|
|
||||||
/// you wish to add from the pop-up menu in the Value field. This list should
|
|
||||||
/// be consistent with the languages listed in the AppLocalizations.supportedLocales
|
|
||||||
/// property.
|
|
||||||
abstract class AppLocalizations {
|
|
||||||
AppLocalizations(String locale)
|
|
||||||
: localeName = intl.Intl.canonicalizedLocale(locale.toString());
|
|
||||||
|
|
||||||
final String localeName;
|
|
||||||
|
|
||||||
static AppLocalizations of(BuildContext context) {
|
|
||||||
return Localizations.of<AppLocalizations>(context, AppLocalizations)!;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const LocalizationsDelegate<AppLocalizations> delegate =
|
|
||||||
_AppLocalizationsDelegate();
|
|
||||||
|
|
||||||
/// A list of this localizations delegate along with the default localizations
|
|
||||||
/// delegates.
|
|
||||||
///
|
|
||||||
/// Returns a list of localizations delegates containing this delegate along with
|
|
||||||
/// GlobalMaterialLocalizations.delegate, GlobalCupertinoLocalizations.delegate,
|
|
||||||
/// and GlobalWidgetsLocalizations.delegate.
|
|
||||||
///
|
|
||||||
/// Additional delegates can be added by appending to this list in
|
|
||||||
/// MaterialApp. This list does not have to be used at all if a custom list
|
|
||||||
/// of delegates is preferred or required.
|
|
||||||
static const List<LocalizationsDelegate<dynamic>> localizationsDelegates =
|
|
||||||
<LocalizationsDelegate<dynamic>>[
|
|
||||||
delegate,
|
|
||||||
GlobalMaterialLocalizations.delegate,
|
|
||||||
GlobalCupertinoLocalizations.delegate,
|
|
||||||
GlobalWidgetsLocalizations.delegate,
|
|
||||||
];
|
|
||||||
|
|
||||||
/// A list of this localizations delegate's supported locales.
|
|
||||||
static const List<Locale> supportedLocales = <Locale>[
|
|
||||||
Locale('en'),
|
|
||||||
Locale('es'),
|
|
||||||
Locale('zh'),
|
|
||||||
Locale('zh', 'TW'),
|
|
||||||
];
|
|
||||||
|
|
||||||
/// No description provided for @appTitle.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'PDF Signature'**
|
|
||||||
String get appTitle;
|
|
||||||
|
|
||||||
/// Generic error text with message
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'Error: {message}'**
|
|
||||||
String errorWithMessage(String message);
|
|
||||||
|
|
||||||
/// No description provided for @settings.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'Settings'**
|
|
||||||
String get settings;
|
|
||||||
|
|
||||||
/// No description provided for @theme.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'Theme'**
|
|
||||||
String get theme;
|
|
||||||
|
|
||||||
/// No description provided for @themeLight.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'Light'**
|
|
||||||
String get themeLight;
|
|
||||||
|
|
||||||
/// No description provided for @themeDark.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'Dark'**
|
|
||||||
String get themeDark;
|
|
||||||
|
|
||||||
/// No description provided for @themeSystem.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'System'**
|
|
||||||
String get themeSystem;
|
|
||||||
|
|
||||||
/// No description provided for @language.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'Language'**
|
|
||||||
String get language;
|
|
||||||
|
|
||||||
/// No description provided for @languageEnglish.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'English'**
|
|
||||||
String get languageEnglish;
|
|
||||||
|
|
||||||
/// No description provided for @languageChineseTraditional.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'Traditional Chinese'**
|
|
||||||
String get languageChineseTraditional;
|
|
||||||
|
|
||||||
/// No description provided for @languageSpanish.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'Spanish'**
|
|
||||||
String get languageSpanish;
|
|
||||||
|
|
||||||
/// No description provided for @resetToDefaults.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'Reset to defaults'**
|
|
||||||
String get resetToDefaults;
|
|
||||||
|
|
||||||
/// No description provided for @openPdf.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'Open PDF...'**
|
|
||||||
String get openPdf;
|
|
||||||
|
|
||||||
/// No description provided for @prev.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'Prev'**
|
|
||||||
String get prev;
|
|
||||||
|
|
||||||
/// No description provided for @next.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'Next'**
|
|
||||||
String get next;
|
|
||||||
|
|
||||||
/// Label showing current page and total
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'Page {current}/{total}'**
|
|
||||||
String pageInfo(int current, int total);
|
|
||||||
|
|
||||||
/// No description provided for @goTo.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'Go to:'**
|
|
||||||
String get goTo;
|
|
||||||
|
|
||||||
/// No description provided for @dpi.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'DPI:'**
|
|
||||||
String get dpi;
|
|
||||||
|
|
||||||
/// No description provided for @saveSignedPdf.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'Save Signed PDF'**
|
|
||||||
String get saveSignedPdf;
|
|
||||||
|
|
||||||
/// No description provided for @loadSignatureFromFile.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'Load Signature from file'**
|
|
||||||
String get loadSignatureFromFile;
|
|
||||||
|
|
||||||
/// No description provided for @drawSignature.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'Draw Signature'**
|
|
||||||
String get drawSignature;
|
|
||||||
|
|
||||||
/// No description provided for @noPdfLoaded.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'No PDF loaded'**
|
|
||||||
String get noPdfLoaded;
|
|
||||||
|
|
||||||
/// No description provided for @signature.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'Signature'**
|
|
||||||
String get signature;
|
|
||||||
|
|
||||||
/// No description provided for @lockAspectRatio.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'Lock aspect ratio'**
|
|
||||||
String get lockAspectRatio;
|
|
||||||
|
|
||||||
/// No description provided for @backgroundRemoval.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'Background removal'**
|
|
||||||
String get backgroundRemoval;
|
|
||||||
|
|
||||||
/// No description provided for @contrast.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'Contrast'**
|
|
||||||
String get contrast;
|
|
||||||
|
|
||||||
/// No description provided for @brightness.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'Brightness'**
|
|
||||||
String get brightness;
|
|
||||||
|
|
||||||
/// No description provided for @exportingPleaseWait.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'Exporting... Please wait'**
|
|
||||||
String get exportingPleaseWait;
|
|
||||||
|
|
||||||
/// No description provided for @nothingToSaveYet.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'Nothing to save yet'**
|
|
||||||
String get nothingToSaveYet;
|
|
||||||
|
|
||||||
/// Snackbar text showing where file saved
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'Saved: {path}'**
|
|
||||||
String savedWithPath(String path);
|
|
||||||
|
|
||||||
/// No description provided for @failedToSavePdf.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'Failed to save PDF'**
|
|
||||||
String get failedToSavePdf;
|
|
||||||
|
|
||||||
/// No description provided for @downloadStarted.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'Download started'**
|
|
||||||
String get downloadStarted;
|
|
||||||
|
|
||||||
/// No description provided for @failedToGeneratePdf.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'Failed to generate PDF'**
|
|
||||||
String get failedToGeneratePdf;
|
|
||||||
|
|
||||||
/// No description provided for @invalidOrUnsupportedFile.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'Invalid or unsupported file'**
|
|
||||||
String get invalidOrUnsupportedFile;
|
|
||||||
|
|
||||||
/// No description provided for @confirm.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'Confirm'**
|
|
||||||
String get confirm;
|
|
||||||
|
|
||||||
/// No description provided for @undo.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'Undo'**
|
|
||||||
String get undo;
|
|
||||||
|
|
||||||
/// No description provided for @clear.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'Clear'**
|
|
||||||
String get clear;
|
|
||||||
}
|
|
||||||
|
|
||||||
class _AppLocalizationsDelegate
|
|
||||||
extends LocalizationsDelegate<AppLocalizations> {
|
|
||||||
const _AppLocalizationsDelegate();
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<AppLocalizations> load(Locale locale) {
|
|
||||||
return SynchronousFuture<AppLocalizations>(lookupAppLocalizations(locale));
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
bool isSupported(Locale locale) =>
|
|
||||||
<String>['en', 'es', 'zh'].contains(locale.languageCode);
|
|
||||||
|
|
||||||
@override
|
|
||||||
bool shouldReload(_AppLocalizationsDelegate old) => false;
|
|
||||||
}
|
|
||||||
|
|
||||||
AppLocalizations lookupAppLocalizations(Locale locale) {
|
|
||||||
// Lookup logic when language+country codes are specified.
|
|
||||||
switch (locale.languageCode) {
|
|
||||||
case 'zh':
|
|
||||||
{
|
|
||||||
switch (locale.countryCode) {
|
|
||||||
case 'TW':
|
|
||||||
return AppLocalizationsZhTw();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Lookup logic when only language code is specified.
|
|
||||||
switch (locale.languageCode) {
|
|
||||||
case 'en':
|
|
||||||
return AppLocalizationsEn();
|
|
||||||
case 'es':
|
|
||||||
return AppLocalizationsEs();
|
|
||||||
case 'zh':
|
|
||||||
return AppLocalizationsZh();
|
|
||||||
}
|
|
||||||
|
|
||||||
throw FlutterError(
|
|
||||||
'AppLocalizations.delegate failed to load unsupported locale "$locale". This is likely '
|
|
||||||
'an issue with the localizations generation tool. Please file an issue '
|
|
||||||
'on GitHub with a reproducible sample app and the gen-l10n configuration '
|
|
||||||
'that was used.',
|
|
||||||
);
|
|
||||||
}
|
|
|
@ -1,127 +0,0 @@
|
||||||
// ignore: unused_import
|
|
||||||
import 'package:intl/intl.dart' as intl;
|
|
||||||
import 'app_localizations.dart';
|
|
||||||
|
|
||||||
// ignore_for_file: type=lint
|
|
||||||
|
|
||||||
/// The translations for English (`en`).
|
|
||||||
class AppLocalizationsEn extends AppLocalizations {
|
|
||||||
AppLocalizationsEn([String locale = 'en']) : super(locale);
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get appTitle => 'PDF Signature';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String errorWithMessage(String message) {
|
|
||||||
return 'Error: $message';
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get settings => 'Settings';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get theme => 'Theme';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get themeLight => 'Light';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get themeDark => 'Dark';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get themeSystem => 'System';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get language => 'Language';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get languageEnglish => 'English';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get languageChineseTraditional => 'Traditional Chinese';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get languageSpanish => 'Spanish';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get resetToDefaults => 'Reset to defaults';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get openPdf => 'Open PDF...';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get prev => 'Prev';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get next => 'Next';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String pageInfo(int current, int total) {
|
|
||||||
return 'Page $current/$total';
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get goTo => 'Go to:';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get dpi => 'DPI:';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get saveSignedPdf => 'Save Signed PDF';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get loadSignatureFromFile => 'Load Signature from file';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get drawSignature => 'Draw Signature';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get noPdfLoaded => 'No PDF loaded';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get signature => 'Signature';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get lockAspectRatio => 'Lock aspect ratio';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get backgroundRemoval => 'Background removal';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get contrast => 'Contrast';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get brightness => 'Brightness';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get exportingPleaseWait => 'Exporting... Please wait';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get nothingToSaveYet => 'Nothing to save yet';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String savedWithPath(String path) {
|
|
||||||
return 'Saved: $path';
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get failedToSavePdf => 'Failed to save PDF';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get downloadStarted => 'Download started';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get failedToGeneratePdf => 'Failed to generate PDF';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get invalidOrUnsupportedFile => 'Invalid or unsupported file';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get confirm => 'Confirm';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get undo => 'Undo';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get clear => 'Clear';
|
|
||||||
}
|
|
|
@ -1,127 +0,0 @@
|
||||||
// ignore: unused_import
|
|
||||||
import 'package:intl/intl.dart' as intl;
|
|
||||||
import 'app_localizations.dart';
|
|
||||||
|
|
||||||
// ignore_for_file: type=lint
|
|
||||||
|
|
||||||
/// The translations for Spanish Castilian (`es`).
|
|
||||||
class AppLocalizationsEs extends AppLocalizations {
|
|
||||||
AppLocalizationsEs([String locale = 'es']) : super(locale);
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get appTitle => 'Firma PDF';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String errorWithMessage(String message) {
|
|
||||||
return 'Error: $message';
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get settings => 'Ajustes';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get theme => 'Tema';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get themeLight => 'Claro';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get themeDark => 'Oscuro';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get themeSystem => 'Del sistema';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get language => 'Idioma';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get languageEnglish => 'Inglés';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get languageChineseTraditional => 'Chino tradicional';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get languageSpanish => 'Español';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get resetToDefaults => 'Restablecer valores';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get openPdf => 'Abrir PDF…';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get prev => 'Anterior';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get next => 'Siguiente';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String pageInfo(int current, int total) {
|
|
||||||
return 'Página $current/$total';
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get goTo => 'Ir a:';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get dpi => 'DPI:';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get saveSignedPdf => 'Guardar PDF firmado';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get loadSignatureFromFile => 'Cargar firma desde archivo';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get drawSignature => 'Dibujar firma';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get noPdfLoaded => 'No hay PDF cargado';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get signature => 'Firma';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get lockAspectRatio => 'Bloquear relación de aspecto';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get backgroundRemoval => 'Eliminación de fondo';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get contrast => 'Contraste';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get brightness => 'Brillo';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get exportingPleaseWait => 'Exportando... Por favor espera';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get nothingToSaveYet => 'Nada que guardar todavía';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String savedWithPath(String path) {
|
|
||||||
return 'Guardado: $path';
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get failedToSavePdf => 'Error al guardar el PDF';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get downloadStarted => 'Descarga iniciada';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get failedToGeneratePdf => 'Error al generar el PDF';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get invalidOrUnsupportedFile => 'Archivo no válido o no compatible';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get confirm => 'Confirmar';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get undo => 'Deshacer';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get clear => 'Limpiar';
|
|
||||||
}
|
|
|
@ -1,249 +0,0 @@
|
||||||
// ignore: unused_import
|
|
||||||
import 'package:intl/intl.dart' as intl;
|
|
||||||
import 'app_localizations.dart';
|
|
||||||
|
|
||||||
// ignore_for_file: type=lint
|
|
||||||
|
|
||||||
/// The translations for Chinese (`zh`).
|
|
||||||
class AppLocalizationsZh extends AppLocalizations {
|
|
||||||
AppLocalizationsZh([String locale = 'zh']) : super(locale);
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get appTitle => 'PDF 簽名';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String errorWithMessage(String message) {
|
|
||||||
return '錯誤:$message';
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get settings => '設定';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get theme => '主題';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get themeLight => '淺色';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get themeDark => '深色';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get themeSystem => '系統';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get language => '語言';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get languageEnglish => '英文';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get languageChineseTraditional => '繁體中文';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get languageSpanish => '西班牙文';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get resetToDefaults => '重設為預設值';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get openPdf => '開啟 PDF…';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get prev => '上一頁';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get next => '下一頁';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String pageInfo(int current, int total) {
|
|
||||||
return '第 $current/$total 頁';
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get goTo => '前往:';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get dpi => 'DPI:';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get saveSignedPdf => '儲存已簽名 PDF';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get loadSignatureFromFile => '從檔案載入簽名';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get drawSignature => '手寫簽名';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get noPdfLoaded => '尚未載入 PDF';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get signature => '簽名';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get lockAspectRatio => '鎖定長寬比';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get backgroundRemoval => '去除背景';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get contrast => '對比';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get brightness => '亮度';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get exportingPleaseWait => '匯出中…請稍候';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get nothingToSaveYet => '尚無可儲存的內容';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String savedWithPath(String path) {
|
|
||||||
return '已儲存:$path';
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get failedToSavePdf => '儲存 PDF 失敗';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get downloadStarted => '已開始下載';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get failedToGeneratePdf => '產生 PDF 失敗';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get invalidOrUnsupportedFile => '無效或不支援的檔案';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get confirm => '確認';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get undo => '復原';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get clear => '清除';
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The translations for Chinese, as used in Taiwan (`zh_TW`).
|
|
||||||
class AppLocalizationsZhTw extends AppLocalizationsZh {
|
|
||||||
AppLocalizationsZhTw() : super('zh_TW');
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get appTitle => 'PDF 簽名';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String errorWithMessage(String message) {
|
|
||||||
return '錯誤:$message';
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get settings => '設定';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get theme => '主題';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get themeLight => '淺色';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get themeDark => '深色';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get themeSystem => '系統';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get language => '語言';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get languageEnglish => '英文';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get languageChineseTraditional => '繁體中文';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get languageSpanish => '西班牙文';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get resetToDefaults => '重設為預設值';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get openPdf => '開啟 PDF…';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get prev => '上一頁';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get next => '下一頁';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String pageInfo(int current, int total) {
|
|
||||||
return '第 $current/$total 頁';
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get goTo => '前往:';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get dpi => 'DPI:';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get saveSignedPdf => '儲存已簽名 PDF';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get loadSignatureFromFile => '從檔案載入簽名';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get drawSignature => '手寫簽名';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get noPdfLoaded => '尚未載入 PDF';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get signature => '簽名';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get lockAspectRatio => '鎖定長寬比';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get backgroundRemoval => '去除背景';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get contrast => '對比';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get brightness => '亮度';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get exportingPleaseWait => '匯出中…請稍候';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get nothingToSaveYet => '尚無可儲存的內容';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String savedWithPath(String path) {
|
|
||||||
return '已儲存:$path';
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get failedToSavePdf => '儲存 PDF 失敗';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get downloadStarted => '已開始下載';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get failedToGeneratePdf => '產生 PDF 失敗';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get invalidOrUnsupportedFile => '無效或不支援的檔案';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get confirm => '確認';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get undo => '復原';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get clear => '清除';
|
|
||||||
}
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
{
|
||||||
|
"appTitle": "Підпис PDF",
|
||||||
|
"backgroundRemoval": "Видалення фону",
|
||||||
|
"brightness": "Яскравість",
|
||||||
|
"clear": "Очистити",
|
||||||
|
"confirm": "Підтвердити",
|
||||||
|
"contrast": "Контрастність",
|
||||||
|
"createNewSignature": "Створити новий підпис",
|
||||||
|
"delete": "Видалити",
|
||||||
|
"downloadStarted": "Завантаження розпочато",
|
||||||
|
"dpi": "DPI:",
|
||||||
|
"drawSignature": "Намалювати підпис",
|
||||||
|
"errorWithMessage": "Помилка: {message}",
|
||||||
|
"exportingPleaseWait": "Експортування... Зачекайте",
|
||||||
|
"failedToGeneratePdf": "Не вдалося створити PDF",
|
||||||
|
"failedToSavePdf": "Не вдалося зберегти PDF",
|
||||||
|
"goTo": "Перейти до:",
|
||||||
|
"invalidOrUnsupportedFile": "Недійсний або непідтримуваний файл",
|
||||||
|
"language": "Мова",
|
||||||
|
"loadSignatureFromFile": "Завантажити підпис з файлу",
|
||||||
|
"lockAspectRatio": "Зафіксувати співвідношення сторін",
|
||||||
|
"longPressOrRightClickTheSignatureToConfirmOrDelete": "Довго натисніть або клацніть правою кнопкою миші на підпис, щоб підтвердити або видалити.",
|
||||||
|
"next": "Далі",
|
||||||
|
"noPdfLoaded": "PDF не завантажено",
|
||||||
|
"nothingToSaveYet": "Ще нічого не потрібно зберігати",
|
||||||
|
"openPdf": "Відкрити PDF...",
|
||||||
|
"pageInfo": "Сторінка {current}/{total}",
|
||||||
|
"prev": "Попередня",
|
||||||
|
"resetToDefaults": "Скинути до значень за замовчуванням",
|
||||||
|
"savedWithPath": "Збережено: {path}",
|
||||||
|
"saveSignedPdf": "Зберегти підписаний PDF",
|
||||||
|
"settings": "Налаштування",
|
||||||
|
"signature": "Підпис",
|
||||||
|
"theme": "Тема",
|
||||||
|
"themeDark": "Темна",
|
||||||
|
"themeLight": "Світла",
|
||||||
|
"themeSystem": "Системна",
|
||||||
|
"undo": "Відмінити"
|
||||||
|
}
|
|
@ -1,44 +1,40 @@
|
||||||
{
|
{
|
||||||
"@@locale": "zh",
|
"@@locale": "zh",
|
||||||
"appTitle": "PDF 簽名",
|
"appTitle": "PDF 簽名",
|
||||||
"errorWithMessage": "錯誤:{message}",
|
|
||||||
|
|
||||||
"settings": "設定",
|
|
||||||
"theme": "主題",
|
|
||||||
"themeLight": "淺色",
|
|
||||||
"themeDark": "深色",
|
|
||||||
"themeSystem": "系統",
|
|
||||||
"language": "語言",
|
|
||||||
"languageEnglish": "英文",
|
|
||||||
"languageChineseTraditional": "繁體中文",
|
|
||||||
"languageSpanish": "西班牙文",
|
|
||||||
"resetToDefaults": "重設為預設值",
|
|
||||||
|
|
||||||
"openPdf": "開啟 PDF…",
|
|
||||||
"prev": "上一頁",
|
|
||||||
"next": "下一頁",
|
|
||||||
"pageInfo": "第 {current}/{total} 頁",
|
|
||||||
"goTo": "前往:",
|
|
||||||
"dpi": "DPI:",
|
|
||||||
"saveSignedPdf": "儲存已簽名 PDF",
|
|
||||||
"loadSignatureFromFile": "從檔案載入簽名",
|
|
||||||
"drawSignature": "手寫簽名",
|
|
||||||
"noPdfLoaded": "尚未載入 PDF",
|
|
||||||
"signature": "簽名",
|
|
||||||
"lockAspectRatio": "鎖定長寬比",
|
|
||||||
"backgroundRemoval": "去除背景",
|
"backgroundRemoval": "去除背景",
|
||||||
"contrast": "對比",
|
|
||||||
"brightness": "亮度",
|
"brightness": "亮度",
|
||||||
"exportingPleaseWait": "匯出中…請稍候",
|
"clear": "清除",
|
||||||
|
|
||||||
"nothingToSaveYet": "尚無可儲存的內容",
|
|
||||||
"savedWithPath": "已儲存:{path}",
|
|
||||||
"failedToSavePdf": "儲存 PDF 失敗",
|
|
||||||
"downloadStarted": "已開始下載",
|
|
||||||
"failedToGeneratePdf": "產生 PDF 失敗",
|
|
||||||
"invalidOrUnsupportedFile": "無效或不支援的檔案",
|
|
||||||
|
|
||||||
"confirm": "確認",
|
"confirm": "確認",
|
||||||
"undo": "復原",
|
"contrast": "對比",
|
||||||
"clear": "清除"
|
"createNewSignature": "建立新簽名",
|
||||||
|
"delete": "刪除",
|
||||||
|
"downloadStarted": "已開始下載",
|
||||||
|
"dpi": "DPI:",
|
||||||
|
"drawSignature": "手寫簽名",
|
||||||
|
"errorWithMessage": "錯誤:{message}",
|
||||||
|
"exportingPleaseWait": "匯出中…請稍候",
|
||||||
|
"failedToGeneratePdf": "產生 PDF 失敗",
|
||||||
|
"failedToSavePdf": "儲存 PDF 失敗",
|
||||||
|
"goTo": "前往:",
|
||||||
|
"invalidOrUnsupportedFile": "無效或不支援的檔案",
|
||||||
|
"language": "語言",
|
||||||
|
"loadSignatureFromFile": "從檔案載入簽名",
|
||||||
|
"lockAspectRatio": "鎖定長寬比",
|
||||||
|
"longPressOrRightClickTheSignatureToConfirmOrDelete": "長按或右鍵點擊簽名以確認或刪除。",
|
||||||
|
"next": "下一頁",
|
||||||
|
"noPdfLoaded": "尚未載入 PDF",
|
||||||
|
"nothingToSaveYet": "尚無可儲存的內容",
|
||||||
|
"openPdf": "開啟 PDF…",
|
||||||
|
"pageInfo": "第 {current}/{total} 頁",
|
||||||
|
"prev": "上一頁",
|
||||||
|
"resetToDefaults": "重設為預設值",
|
||||||
|
"savedWithPath": "已儲存:{path}",
|
||||||
|
"saveSignedPdf": "儲存已簽名 PDF",
|
||||||
|
"settings": "設定",
|
||||||
|
"signature": "簽名",
|
||||||
|
"theme": "主題",
|
||||||
|
"themeDark": "深色",
|
||||||
|
"themeLight": "淺色",
|
||||||
|
"themeSystem": "系統",
|
||||||
|
"undo": "復原"
|
||||||
}
|
}
|
|
@ -0,0 +1,39 @@
|
||||||
|
{
|
||||||
|
"appTitle": "PDF 签名",
|
||||||
|
"backgroundRemoval": "背景移除",
|
||||||
|
"brightness": "亮度",
|
||||||
|
"clear": "清除",
|
||||||
|
"confirm": "确认",
|
||||||
|
"contrast": "对比度",
|
||||||
|
"createNewSignature": "创建新的签名",
|
||||||
|
"delete": "删除",
|
||||||
|
"downloadStarted": "下载已开始",
|
||||||
|
"dpi": "DPI:",
|
||||||
|
"drawSignature": "绘制签名",
|
||||||
|
"errorWithMessage": "错误:{message}",
|
||||||
|
"exportingPleaseWait": "正在导出... 请稍候",
|
||||||
|
"failedToGeneratePdf": "PDF 生成失败",
|
||||||
|
"failedToSavePdf": "PDF 保存失败",
|
||||||
|
"goTo": "跳转到:",
|
||||||
|
"invalidOrUnsupportedFile": "无效或不支持的文件",
|
||||||
|
"language": "语言",
|
||||||
|
"loadSignatureFromFile": "从文件加载签名",
|
||||||
|
"lockAspectRatio": "锁定纵横比",
|
||||||
|
"longPressOrRightClickTheSignatureToConfirmOrDelete": "长按或右键单击签名以确认或删除。",
|
||||||
|
"next": "下一步",
|
||||||
|
"noPdfLoaded": "未加载 PDF",
|
||||||
|
"nothingToSaveYet": "尚无内容保存",
|
||||||
|
"openPdf": "打开 PDF...",
|
||||||
|
"pageInfo": "第 {current} 页 / 共 {total} 页",
|
||||||
|
"prev": "上一页",
|
||||||
|
"resetToDefaults": "恢复默认值",
|
||||||
|
"savedWithPath": "已保存:{path}",
|
||||||
|
"saveSignedPdf": "保存已签名的 PDF",
|
||||||
|
"settings": "设置",
|
||||||
|
"signature": "签名",
|
||||||
|
"theme": "主题",
|
||||||
|
"themeDark": "深色",
|
||||||
|
"themeLight": "浅色",
|
||||||
|
"themeSystem": "系统",
|
||||||
|
"undo": "撤销"
|
||||||
|
}
|
|
@ -1,44 +1,40 @@
|
||||||
{
|
{
|
||||||
"@@locale": "zh_TW",
|
"@@locale": "zh_TW",
|
||||||
"appTitle": "PDF 簽名",
|
"appTitle": "PDF 簽名",
|
||||||
"errorWithMessage": "錯誤:{message}",
|
|
||||||
|
|
||||||
"settings": "設定",
|
|
||||||
"theme": "主題",
|
|
||||||
"themeLight": "淺色",
|
|
||||||
"themeDark": "深色",
|
|
||||||
"themeSystem": "系統",
|
|
||||||
"language": "語言",
|
|
||||||
"languageEnglish": "英文",
|
|
||||||
"languageChineseTraditional": "繁體中文",
|
|
||||||
"languageSpanish": "西班牙文",
|
|
||||||
"resetToDefaults": "重設為預設值",
|
|
||||||
|
|
||||||
"openPdf": "開啟 PDF…",
|
|
||||||
"prev": "上一頁",
|
|
||||||
"next": "下一頁",
|
|
||||||
"pageInfo": "第 {current}/{total} 頁",
|
|
||||||
"goTo": "前往:",
|
|
||||||
"dpi": "DPI:",
|
|
||||||
"saveSignedPdf": "儲存已簽名 PDF",
|
|
||||||
"loadSignatureFromFile": "從檔案載入簽名",
|
|
||||||
"drawSignature": "手寫簽名",
|
|
||||||
"noPdfLoaded": "尚未載入 PDF",
|
|
||||||
"signature": "簽名",
|
|
||||||
"lockAspectRatio": "鎖定長寬比",
|
|
||||||
"backgroundRemoval": "去除背景",
|
"backgroundRemoval": "去除背景",
|
||||||
"contrast": "對比",
|
|
||||||
"brightness": "亮度",
|
"brightness": "亮度",
|
||||||
"exportingPleaseWait": "匯出中…請稍候",
|
"clear": "清除",
|
||||||
|
|
||||||
"nothingToSaveYet": "尚無可儲存的內容",
|
|
||||||
"savedWithPath": "已儲存:{path}",
|
|
||||||
"failedToSavePdf": "儲存 PDF 失敗",
|
|
||||||
"downloadStarted": "已開始下載",
|
|
||||||
"failedToGeneratePdf": "產生 PDF 失敗",
|
|
||||||
"invalidOrUnsupportedFile": "無效或不支援的檔案",
|
|
||||||
|
|
||||||
"confirm": "確認",
|
"confirm": "確認",
|
||||||
"undo": "復原",
|
"contrast": "對比",
|
||||||
"clear": "清除"
|
"createNewSignature": "建立新簽名",
|
||||||
|
"delete": "刪除",
|
||||||
|
"downloadStarted": "已開始下載",
|
||||||
|
"dpi": "DPI:",
|
||||||
|
"drawSignature": "手寫簽名",
|
||||||
|
"errorWithMessage": "錯誤:{message}",
|
||||||
|
"exportingPleaseWait": "匯出中…請稍候",
|
||||||
|
"failedToGeneratePdf": "產生 PDF 失敗",
|
||||||
|
"failedToSavePdf": "儲存 PDF 失敗",
|
||||||
|
"goTo": "前往:",
|
||||||
|
"invalidOrUnsupportedFile": "無效或不支援的檔案",
|
||||||
|
"language": "語言",
|
||||||
|
"loadSignatureFromFile": "從檔案載入簽名",
|
||||||
|
"lockAspectRatio": "鎖定長寬比",
|
||||||
|
"longPressOrRightClickTheSignatureToConfirmOrDelete": "長按或右鍵點擊簽名以確認或刪除。",
|
||||||
|
"next": "下一頁",
|
||||||
|
"noPdfLoaded": "尚未載入 PDF",
|
||||||
|
"nothingToSaveYet": "尚無可儲存的內容",
|
||||||
|
"openPdf": "開啟 PDF…",
|
||||||
|
"pageInfo": "第 {current}/{total} 頁",
|
||||||
|
"prev": "上一頁",
|
||||||
|
"resetToDefaults": "重設為預設值",
|
||||||
|
"savedWithPath": "已儲存:{path}",
|
||||||
|
"saveSignedPdf": "儲存已簽名 PDF",
|
||||||
|
"settings": "設定",
|
||||||
|
"signature": "簽名",
|
||||||
|
"theme": "主題",
|
||||||
|
"themeDark": "深色",
|
||||||
|
"themeLight": "淺色",
|
||||||
|
"themeSystem": "系統",
|
||||||
|
"undo": "復原"
|
||||||
}
|
}
|
|
@ -41,11 +41,11 @@ class PdfPageArea extends ConsumerWidget {
|
||||||
globalPos.dx,
|
globalPos.dx,
|
||||||
globalPos.dy,
|
globalPos.dy,
|
||||||
),
|
),
|
||||||
items: const [
|
items: [
|
||||||
PopupMenuItem<String>(
|
PopupMenuItem<String>(
|
||||||
key: Key('ctx_delete_signature'),
|
key: Key('ctx_delete_signature'),
|
||||||
value: 'delete',
|
value: 'delete',
|
||||||
child: Text('Delete'),
|
child: Text(AppLocalizations.of(context).delete),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
@ -281,16 +281,16 @@ class PdfPageArea extends ConsumerWidget {
|
||||||
pos.dx,
|
pos.dx,
|
||||||
pos.dy,
|
pos.dy,
|
||||||
),
|
),
|
||||||
items: const [
|
items: [
|
||||||
PopupMenuItem<String>(
|
PopupMenuItem<String>(
|
||||||
key: Key('ctx_active_confirm'),
|
key: Key('ctx_active_confirm'),
|
||||||
value: 'confirm',
|
value: 'confirm',
|
||||||
child: Text('Confirm'),
|
child: Text(AppLocalizations.of(context).confirm),
|
||||||
),
|
),
|
||||||
PopupMenuItem<String>(
|
PopupMenuItem<String>(
|
||||||
key: Key('ctx_active_delete'),
|
key: Key('ctx_active_delete'),
|
||||||
value: 'delete',
|
value: 'delete',
|
||||||
child: Text('Delete'),
|
child: Text(AppLocalizations.of(context).delete),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
).then((choice) {
|
).then((choice) {
|
||||||
|
@ -311,16 +311,16 @@ class PdfPageArea extends ConsumerWidget {
|
||||||
pos.dx,
|
pos.dx,
|
||||||
pos.dy,
|
pos.dy,
|
||||||
),
|
),
|
||||||
items: const [
|
items: [
|
||||||
PopupMenuItem<String>(
|
PopupMenuItem<String>(
|
||||||
key: Key('ctx_active_confirm_lp'),
|
key: Key('ctx_active_confirm_lp'),
|
||||||
value: 'confirm',
|
value: 'confirm',
|
||||||
child: Text('Confirm'),
|
child: Text(AppLocalizations.of(context).confirm),
|
||||||
),
|
),
|
||||||
PopupMenuItem<String>(
|
PopupMenuItem<String>(
|
||||||
key: Key('ctx_active_delete_lp'),
|
key: Key('ctx_active_delete_lp'),
|
||||||
value: 'delete',
|
value: 'delete',
|
||||||
child: Text('Delete'),
|
child: Text(AppLocalizations.of(context).delete),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
).then((choice) {
|
).then((choice) {
|
||||||
|
|
|
@ -79,9 +79,11 @@ class _PdfSignatureHomePageState extends ConsumerState<PdfSignatureHomePage> {
|
||||||
.setSignedPage(ref.read(pdfProvider).currentPage);
|
.setSignedPage(ref.read(pdfProvider).currentPage);
|
||||||
// Hint: how to confirm/delete via context menu
|
// Hint: how to confirm/delete via context menu
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
const SnackBar(
|
SnackBar(
|
||||||
content: Text(
|
content: Text(
|
||||||
'Long-press or right-click the signature to Confirm or Delete.',
|
AppLocalizations.of(
|
||||||
|
context,
|
||||||
|
).longPressOrRightClickTheSignatureToConfirmOrDelete,
|
||||||
),
|
),
|
||||||
duration: Duration(seconds: 3),
|
duration: Duration(seconds: 3),
|
||||||
),
|
),
|
||||||
|
|
|
@ -129,7 +129,7 @@ class PdfToolbar extends ConsumerWidget {
|
||||||
OutlinedButton(
|
OutlinedButton(
|
||||||
key: const Key('btn_create_signature'),
|
key: const Key('btn_create_signature'),
|
||||||
onPressed: disabled || !pdf.loaded ? null : onCreateSignature,
|
onPressed: disabled || !pdf.loaded ? null : onCreateSignature,
|
||||||
child: const Text('Create new signature'),
|
child: Text(l.createNewSignature),
|
||||||
),
|
),
|
||||||
ElevatedButton(
|
ElevatedButton(
|
||||||
key: const Key('btn_draw_signature'),
|
key: const Key('btn_draw_signature'),
|
||||||
|
|
|
@ -1,32 +1,64 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
|
import 'package:pdf_signature/l10n/app_localizations.dart';
|
||||||
|
import 'package:flutter_localized_locales/flutter_localized_locales.dart';
|
||||||
|
|
||||||
// Simple supported locales
|
// Helpers to work with BCP-47 language tags
|
||||||
const supportedLocales = <Locale>[
|
String toLanguageTag(Locale loc) {
|
||||||
Locale('en'),
|
final lang = loc.languageCode.toLowerCase();
|
||||||
Locale('zh', 'TW'),
|
final region = loc.countryCode;
|
||||||
Locale('es'),
|
if (region == null || region.isEmpty) return lang;
|
||||||
];
|
return '$lang-${region.toUpperCase()}';
|
||||||
|
}
|
||||||
|
|
||||||
|
Locale _parseLanguageTag(String tag) {
|
||||||
|
final cleaned = tag.replaceAll('_', '-');
|
||||||
|
final parts = cleaned.split('-');
|
||||||
|
if (parts.length >= 2 && parts[1].isNotEmpty) {
|
||||||
|
return Locale(parts[0].toLowerCase(), parts[1].toUpperCase());
|
||||||
|
}
|
||||||
|
return Locale(parts[0].toLowerCase());
|
||||||
|
}
|
||||||
|
|
||||||
|
Set<String> _supportedTags() {
|
||||||
|
return AppLocalizations.supportedLocales.map((l) => toLanguageTag(l)).toSet();
|
||||||
|
}
|
||||||
|
|
||||||
// Keys
|
// Keys
|
||||||
const _kTheme = 'theme'; // 'light'|'dark'|'system'
|
const _kTheme = 'theme'; // 'light'|'dark'|'system'
|
||||||
const _kLanguage = 'language'; // 'en'|'zh-TW'|'es'
|
const _kLanguage = 'language'; // BCP-47 tag like 'en', 'zh-TW', 'es'
|
||||||
|
|
||||||
String _normalizeLanguageTag(String tag) {
|
String _normalizeLanguageTag(String tag) {
|
||||||
final parts = tag.split('-');
|
final tags = _supportedTags();
|
||||||
if (parts.isEmpty) return 'en';
|
if (tag.isEmpty) return tags.contains('en') ? 'en' : tags.first;
|
||||||
final primary = parts[0].toLowerCase();
|
// Replace underscore with hyphen and canonicalize case
|
||||||
if (primary == 'en') return 'en';
|
final normalized = () {
|
||||||
if (primary == 'es') return 'es';
|
final t = tag.replaceAll('_', '-');
|
||||||
if (primary == 'zh') {
|
final parts = t.split('-');
|
||||||
final region = parts.length > 1 ? parts[1].toUpperCase() : '';
|
final lang = parts[0].toLowerCase();
|
||||||
if (region == 'TW') return 'zh-TW';
|
if (parts.length >= 2 && parts[1].isNotEmpty) {
|
||||||
// other zh regions not supported; fall back to English
|
return '$lang-${parts[1].toUpperCase()}';
|
||||||
return 'en';
|
|
||||||
}
|
}
|
||||||
// Fallback default
|
return lang;
|
||||||
return 'en';
|
}();
|
||||||
|
|
||||||
|
// Exact match
|
||||||
|
if (tags.contains(normalized)) return normalized;
|
||||||
|
|
||||||
|
// Try fallback to language-only if available
|
||||||
|
final langOnly = normalized.split('-')[0];
|
||||||
|
if (tags.contains(langOnly)) return langOnly;
|
||||||
|
|
||||||
|
// Try to pick first tag with same language
|
||||||
|
final candidate = tags.firstWhere(
|
||||||
|
(t) => t.split('-')[0] == langOnly,
|
||||||
|
orElse: () => '',
|
||||||
|
);
|
||||||
|
if (candidate.isNotEmpty) return candidate;
|
||||||
|
|
||||||
|
// Final fallback to English or first supported
|
||||||
|
return tags.contains('en') ? 'en' : tags.first;
|
||||||
}
|
}
|
||||||
|
|
||||||
class PreferencesState {
|
class PreferencesState {
|
||||||
|
@ -49,7 +81,8 @@ class PreferencesNotifier extends StateNotifier<PreferencesState> {
|
||||||
theme: prefs.getString(_kTheme) ?? 'system',
|
theme: prefs.getString(_kTheme) ?? 'system',
|
||||||
language: _normalizeLanguageTag(
|
language: _normalizeLanguageTag(
|
||||||
prefs.getString(_kLanguage) ??
|
prefs.getString(_kLanguage) ??
|
||||||
WidgetsBinding.instance.platformDispatcher.locale.toLanguageTag(),
|
WidgetsBinding.instance.platformDispatcher.locale
|
||||||
|
.toLanguageTag(),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
) {
|
) {
|
||||||
|
@ -84,7 +117,8 @@ class PreferencesNotifier extends StateNotifier<PreferencesState> {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> resetToDefaults() async {
|
Future<void> resetToDefaults() async {
|
||||||
final device = WidgetsBinding.instance.platformDispatcher.locale.toLanguageTag();
|
final device =
|
||||||
|
WidgetsBinding.instance.platformDispatcher.locale.toLanguageTag();
|
||||||
final normalized = _normalizeLanguageTag(device);
|
final normalized = _normalizeLanguageTag(device);
|
||||||
state = PreferencesState(theme: 'system', language: normalized);
|
state = PreferencesState(theme: 'system', language: normalized);
|
||||||
await prefs.setString(_kTheme, 'system');
|
await prefs.setString(_kTheme, 'system');
|
||||||
|
@ -125,19 +159,28 @@ final themeModeProvider = Provider<ThemeMode>((ref) {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Locale _parseLanguageTag(String tag) {
|
|
||||||
// 'zh-TW' -> ('zh','TW')
|
|
||||||
final parts = tag.split('-');
|
|
||||||
if (parts.length == 2) return Locale(parts[0], parts[1]);
|
|
||||||
return Locale(parts[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
final localeProvider = Provider<Locale?>((ref) {
|
final localeProvider = Provider<Locale?>((ref) {
|
||||||
final prefs = ref.watch(preferencesProvider);
|
final prefs = ref.watch(preferencesProvider);
|
||||||
|
final supported = _supportedTags();
|
||||||
// Return explicit Locale for supported ones; if not supported, null to follow device
|
// Return explicit Locale for supported ones; if not supported, null to follow device
|
||||||
final supported = {'en', 'zh-TW', 'es'};
|
|
||||||
if (supported.contains(prefs.language)) {
|
if (supported.contains(prefs.language)) {
|
||||||
return _parseLanguageTag(prefs.language);
|
return _parseLanguageTag(prefs.language);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/// Provides a map of BCP-47 tag -> autonym (self name), independent of UI locale.
|
||||||
|
final languageAutonymsProvider = FutureProvider<Map<String, String>>((
|
||||||
|
ref,
|
||||||
|
) async {
|
||||||
|
final tags = _supportedTags().toList()..sort();
|
||||||
|
final delegate = LocaleNamesLocalizationsDelegate();
|
||||||
|
final Map<String, String> result = {};
|
||||||
|
for (final tag in tags) {
|
||||||
|
final locale = _parseLanguageTag(tag);
|
||||||
|
final names = await delegate.load(locale);
|
||||||
|
final name = names.nameOf(tag) ?? tag;
|
||||||
|
result[tag] = name;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
});
|
||||||
|
|
|
@ -39,17 +39,26 @@ class SettingsScreen extends ConsumerWidget {
|
||||||
style: const TextStyle(fontWeight: FontWeight.bold),
|
style: const TextStyle(fontWeight: FontWeight.bold),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 8),
|
const SizedBox(height: 8),
|
||||||
DropdownButton<String>(
|
ref
|
||||||
|
.watch(languageAutonymsProvider)
|
||||||
|
.when(
|
||||||
|
loading:
|
||||||
|
() => const SizedBox(
|
||||||
|
height: 48,
|
||||||
|
child: Center(child: CircularProgressIndicator()),
|
||||||
|
),
|
||||||
|
error:
|
||||||
|
(_, __) => DropdownButton<String>(
|
||||||
key: const Key('ddl_language'),
|
key: const Key('ddl_language'),
|
||||||
value: prefs.language,
|
value: prefs.language,
|
||||||
items: [
|
items:
|
||||||
DropdownMenuItem(value: 'en', child: Text(l.languageEnglish)),
|
AppLocalizations.supportedLocales.map((loc) {
|
||||||
DropdownMenuItem(
|
final tag = toLanguageTag(loc);
|
||||||
value: 'zh-TW',
|
return DropdownMenuItem<String>(
|
||||||
child: Text(l.languageChineseTraditional),
|
value: tag,
|
||||||
),
|
child: Text(tag),
|
||||||
DropdownMenuItem(value: 'es', child: Text(l.languageSpanish)),
|
);
|
||||||
],
|
}).toList(),
|
||||||
onChanged:
|
onChanged:
|
||||||
(v) =>
|
(v) =>
|
||||||
v == null
|
v == null
|
||||||
|
@ -58,6 +67,34 @@ class SettingsScreen extends ConsumerWidget {
|
||||||
.read(preferencesProvider.notifier)
|
.read(preferencesProvider.notifier)
|
||||||
.setLanguage(v),
|
.setLanguage(v),
|
||||||
),
|
),
|
||||||
|
data: (names) {
|
||||||
|
final items =
|
||||||
|
AppLocalizations.supportedLocales
|
||||||
|
.map((loc) => toLanguageTag(loc))
|
||||||
|
.toList()
|
||||||
|
..sort();
|
||||||
|
return DropdownButton<String>(
|
||||||
|
key: const Key('ddl_language'),
|
||||||
|
value: prefs.language,
|
||||||
|
items:
|
||||||
|
items
|
||||||
|
.map(
|
||||||
|
(tag) => DropdownMenuItem<String>(
|
||||||
|
value: tag,
|
||||||
|
child: Text(names[tag] ?? tag),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.toList(),
|
||||||
|
onChanged:
|
||||||
|
(v) =>
|
||||||
|
v == null
|
||||||
|
? null
|
||||||
|
: ref
|
||||||
|
.read(preferencesProvider.notifier)
|
||||||
|
.setLanguage(v),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
const Spacer(),
|
const Spacer(),
|
||||||
Align(
|
Align(
|
||||||
alignment: Alignment.bottomRight,
|
alignment: Alignment.bottomRight,
|
||||||
|
|
|
@ -49,6 +49,7 @@ dependencies:
|
||||||
flutter_localizations:
|
flutter_localizations:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
intl: any
|
intl: any
|
||||||
|
flutter_localized_locales: ^2.0.5
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
|
|
@ -30,6 +30,7 @@ const system = _Token('system');
|
||||||
const en = _Token('en');
|
const en = _Token('en');
|
||||||
const es = _Token('es');
|
const es = _Token('es');
|
||||||
const zh = _Token('zh');
|
const zh = _Token('zh');
|
||||||
|
// ignore: constant_identifier_names
|
||||||
const TW = _Token('TW');
|
const TW = _Token('TW');
|
||||||
const theme = _Token('theme');
|
const theme = _Token('theme');
|
||||||
const language = _Token('language');
|
const language = _Token('language');
|
||||||
|
|
Loading…
Reference in New Issue