diff --git a/src/Filee.App/Assets/i18n/ar.json b/src/Filee.App/Assets/i18n/ar.json index 3de1151e..b5b4fede 100644 --- a/src/Filee.App/Assets/i18n/ar.json +++ b/src/Filee.App/Assets/i18n/ar.json @@ -44,6 +44,11 @@ "home.clear_history": "مسح", "home.files": "عدد الملفات: {0}", "home.failed_files": "فشل: {0}", + "home.undo": "تراجع", + "home.undo_hint": "نقل النتائج إلى سلة المحذوفات", + "home.undone": "تم التراجع: النتائج في سلة المحذوفات", + "home.undone_original": "تم التراجع: النتائج في سلة المحذوفات، وكذلك الملفات الأصلية التي حلّت محلها", + "home.undo_failed": "تعذّر نقل {0} إلى سلة المحذوفات: {1}", "donut.center_drag": "اسحب الملفات إلى هنا", "donut.files_same": "{0} × {1}", "donut.files_mixed": "عدد الملفات: {0}", @@ -119,6 +124,7 @@ "trash.no_folder": "لا يوجد مجلد لسلة المحذوفات", "trash.failed": "تعذّر نقله إلى سلة المحذوفات", "trash.cannot_place": "تعذّر حفظ النتيجة في مجلد الأصل", + "trash.changed": "تغيّر بعد التحويل", "notice.empty_spreadsheet_pages_removed": "تمت إزالة صفحات جدول البيانات الفارغة", "notice.ocr_has_text": "كل الصفحات تحتوي على نص بالفعل، لذا نُسخ الملف كما هو", "notice.live_photo_pair": "حُفظ كصورة وملف MOV بالاسم نفسه. استوردهما معًا (صور iCloud أو AirDrop أو تطبيق الصور على Mac) لتحصل على Live Photo", diff --git a/src/Filee.App/Assets/i18n/de.json b/src/Filee.App/Assets/i18n/de.json index fc742a82..47839db8 100644 --- a/src/Filee.App/Assets/i18n/de.json +++ b/src/Filee.App/Assets/i18n/de.json @@ -44,6 +44,11 @@ "home.clear_history": "Leeren", "home.files": "{0} Dateien", "home.failed_files": "{0} fehlgeschlagen", + "home.undo": "Rückgängig", + "home.undo_hint": "Die Ergebnisse in den Papierkorb verschieben", + "home.undone": "Rückgängig gemacht: Die Ergebnisse sind im Papierkorb", + "home.undone_original": "Rückgängig gemacht: Die Ergebnisse sind im Papierkorb, ebenso die Originale, die sie ersetzt hatten", + "home.undo_failed": "{0} konnte nicht in den Papierkorb verschoben werden: {1}", "donut.center_drag": "Dateien hierher ziehen", "donut.files_same": "{0} × {1}", "donut.files_mixed": "{0} Dateien", @@ -119,6 +124,7 @@ "trash.no_folder": "es gibt keinen Papierkorbordner", "trash.failed": "die Datei konnte nicht in den Papierkorb verschoben werden", "trash.cannot_place": "das Ergebnis konnte nicht im Ordner des Originals gespeichert werden", + "trash.changed": "die Datei wurde nach der Umwandlung geändert", "notice.empty_spreadsheet_pages_removed": "Leere Tabellenseiten wurden entfernt", "notice.ocr_has_text": "Alle Seiten enthalten bereits Text. Die Datei wurde unverändert kopiert", "notice.live_photo_pair": "Als Foto und MOV-Datei mit gleichem Namen gespeichert. Importiere beide zusammen (über iCloud-Fotos, AirDrop oder Fotos auf einem Mac), um ein Live Photo zu erhalten", diff --git a/src/Filee.App/Assets/i18n/en.json b/src/Filee.App/Assets/i18n/en.json index 75d0ee92..7ed76479 100644 --- a/src/Filee.App/Assets/i18n/en.json +++ b/src/Filee.App/Assets/i18n/en.json @@ -47,6 +47,11 @@ "home.clear_history": "Clear", "home.files": "{0} files", "home.failed_files": "{0} failed", + "home.undo": "Undo", + "home.undo_hint": "Move the results to the Recycle Bin / Trash", + "home.undone": "Undone: the results are in the Recycle Bin / Trash", + "home.undone_original": "Undone: the results are in the Recycle Bin / Trash, and so are the originals they replaced", + "home.undo_failed": "{0} couldn't be moved to the Recycle Bin / Trash: {1}", "donut.center_drag": "Bring files here", "donut.files_same": "{0} × {1}", @@ -125,6 +130,7 @@ "trash.no_folder": "there is no Trash folder", "trash.failed": "it couldn't be moved to the Recycle Bin / Trash", "trash.cannot_place": "the result couldn't be saved in the original's folder", + "trash.changed": "it was changed after the conversion", "notice.empty_spreadsheet_pages_removed": "Empty spreadsheet pages were removed", "notice.ocr_has_text": "Every page already has text, so it was copied as it is", "notice.live_photo_pair": "Saved as a photo and a MOV with the same name. Import both together (iCloud Photos, AirDrop or Photos on a Mac) to get a Live Photo", diff --git a/src/Filee.App/Assets/i18n/es.json b/src/Filee.App/Assets/i18n/es.json index c074a17f..b43e1cff 100644 --- a/src/Filee.App/Assets/i18n/es.json +++ b/src/Filee.App/Assets/i18n/es.json @@ -44,6 +44,11 @@ "home.clear_history": "Borrar", "home.files": "{0} archivos", "home.failed_files": "{0} con error", + "home.undo": "Deshacer", + "home.undo_hint": "Mover los resultados a la Papelera de reciclaje", + "home.undone": "Deshecho: los resultados están en la Papelera de reciclaje", + "home.undone_original": "Deshecho: los resultados están en la Papelera de reciclaje, igual que los originales que reemplazaron", + "home.undo_failed": "No se pudo mover {0} a la Papelera de reciclaje: {1}", "donut.center_drag": "Trae los archivos aquí", "donut.files_same": "{0} × {1}", "donut.files_mixed": "{0} archivos", @@ -119,6 +124,7 @@ "trash.no_folder": "no hay carpeta de Papelera", "trash.failed": "no se pudo mover a la Papelera de reciclaje", "trash.cannot_place": "no se pudo guardar el resultado en la carpeta del original", + "trash.changed": "cambió después de la conversión", "notice.empty_spreadsheet_pages_removed": "Se eliminaron las páginas vacías de la hoja de cálculo", "notice.ocr_has_text": "Todas las páginas ya tienen texto, así que se copió tal cual", "notice.live_photo_pair": "Guardado como una foto y un MOV con el mismo nombre. Impórtalos juntos (Fotos de iCloud, AirDrop o Fotos en un Mac) para obtener una Live Photo", diff --git a/src/Filee.App/Assets/i18n/fr.json b/src/Filee.App/Assets/i18n/fr.json index 68101164..38cc052c 100644 --- a/src/Filee.App/Assets/i18n/fr.json +++ b/src/Filee.App/Assets/i18n/fr.json @@ -47,6 +47,11 @@ "home.clear_history": "Effacer", "home.files": "{0} fichiers", "home.failed_files": "{0} en échec", + "home.undo": "Annuler", + "home.undo_hint": "Déplacer les résultats dans la Corbeille", + "home.undone": "Annulé : les résultats sont dans la Corbeille", + "home.undone_original": "Annulé : les résultats sont dans la Corbeille, tout comme les originaux qu'ils avaient remplacés", + "home.undo_failed": "Impossible de déplacer {0} dans la Corbeille : {1}", "donut.center_drag": "Amenez les fichiers ici", "donut.files_same": "{0} × {1}", @@ -125,6 +130,7 @@ "trash.no_folder": "il n'y a pas de dossier Corbeille", "trash.failed": "impossible de le déplacer dans la Corbeille", "trash.cannot_place": "impossible d'enregistrer le résultat dans le dossier de l'original", + "trash.changed": "il a été modifié après la conversion", "notice.empty_spreadsheet_pages_removed": "Les pages vides de la feuille de calcul ont été supprimées", "notice.ocr_has_text": "Toutes les pages ont déjà du texte : copié tel quel", "notice.live_photo_pair": "Enregistré en une photo et un MOV de même nom. Importez-les ensemble (Photos iCloud, AirDrop ou Photos sur Mac) pour obtenir une Live Photo", diff --git a/src/Filee.App/Assets/i18n/hi.json b/src/Filee.App/Assets/i18n/hi.json index 957153f4..c4569867 100644 --- a/src/Filee.App/Assets/i18n/hi.json +++ b/src/Filee.App/Assets/i18n/hi.json @@ -44,6 +44,11 @@ "home.clear_history": "साफ़ करें", "home.files": "{0} फ़ाइलें", "home.failed_files": "{0} विफल", + "home.undo": "पूर्ववत करें", + "home.undo_hint": "परिणामों को रीसायकल बिन / ट्रैश में ले जाएँ", + "home.undone": "पूर्ववत किया गया: परिणाम रीसायकल बिन / ट्रैश में हैं", + "home.undone_original": "पूर्ववत किया गया: परिणाम रीसायकल बिन / ट्रैश में हैं, और जिन मूल फ़ाइलों की जगह उन्होंने ली थी वे भी वहीं हैं", + "home.undo_failed": "{0} को रीसायकल बिन / ट्रैश में नहीं ले जाया जा सका: {1}", "donut.center_drag": "फ़ाइलें यहाँ लाएँ", "donut.files_same": "{0} × {1}", "donut.files_mixed": "{0} फ़ाइलें", @@ -119,6 +124,7 @@ "trash.no_folder": "ट्रैश फ़ोल्डर नहीं है", "trash.failed": "इसे रीसायकल बिन / ट्रैश में नहीं ले जाया जा सका", "trash.cannot_place": "परिणाम मूल फ़ाइल के फ़ोल्डर में सेव नहीं हो सका", + "trash.changed": "रूपांतरण के बाद इसे बदला गया", "notice.empty_spreadsheet_pages_removed": "स्प्रेडशीट के खाली पृष्ठ हटा दिए गए", "notice.ocr_has_text": "हर पेज में पहले से टेक्स्ट है, इसलिए फ़ाइल जैसी थी वैसी कॉपी की गई", "notice.live_photo_pair": "एक ही नाम की फ़ोटो और MOV के रूप में सहेजा गया। लाइव फ़ोटो पाने के लिए दोनों को साथ में इम्पोर्ट करें (iCloud Photos, AirDrop या Mac पर Photos)", diff --git a/src/Filee.App/Assets/i18n/ja.json b/src/Filee.App/Assets/i18n/ja.json index 5dcc03f9..a86f97dc 100644 --- a/src/Filee.App/Assets/i18n/ja.json +++ b/src/Filee.App/Assets/i18n/ja.json @@ -44,6 +44,11 @@ "home.clear_history": "消去", "home.files": "{0}個のファイル", "home.failed_files": "{0}件失敗", + "home.undo": "元に戻す", + "home.undo_hint": "結果をごみ箱に移動します", + "home.undone": "元に戻しました: 結果はごみ箱にあります", + "home.undone_original": "元に戻しました: 結果はごみ箱にあり、置き換えられた元のファイルもごみ箱にあります", + "home.undo_failed": "{0} をごみ箱に移動できませんでした: {1}", "donut.center_drag": "ここにファイルをドラッグ", "donut.files_same": "{0} × {1}", "donut.files_mixed": "{0}ファイル", @@ -119,6 +124,7 @@ "trash.no_folder": "ごみ箱フォルダーがありません", "trash.failed": "ごみ箱に移動できませんでした", "trash.cannot_place": "元のファイルのフォルダーに結果を保存できませんでした", + "trash.changed": "変換後に変更されています", "notice.empty_spreadsheet_pages_removed": "スプレッドシートの空白ページを削除しました", "notice.ocr_has_text": "すべてのページにテキストがあるため、元のままコピーしました", "notice.live_photo_pair": "同じ名前の写真とMOVとして保存しました。両方を一緒に取り込むと(iCloud写真、AirDrop、Macの写真アプリ)Live Photoになります", diff --git a/src/Filee.App/Assets/i18n/ko.json b/src/Filee.App/Assets/i18n/ko.json index 5e899b54..3ab3e257 100644 --- a/src/Filee.App/Assets/i18n/ko.json +++ b/src/Filee.App/Assets/i18n/ko.json @@ -47,6 +47,11 @@ "home.clear_history": "지우기", "home.files": "파일 {0}개", "home.failed_files": "{0}개 실패", + "home.undo": "되돌리기", + "home.undo_hint": "결과를 휴지통으로 옮겨요", + "home.undone": "되돌렸어요: 결과는 휴지통에 있어요", + "home.undone_original": "되돌렸어요: 결과는 휴지통에 있고, 결과가 대신했던 원본도 휴지통에 있어요", + "home.undo_failed": "{0}을(를) 휴지통으로 옮기지 못했어요: {1}", "donut.center_drag": "파일을 이쪽으로", "donut.files_same": "{1} {0}개", @@ -125,6 +130,7 @@ "trash.no_folder": "휴지통 폴더가 없어요", "trash.failed": "휴지통으로 옮기지 못했어요", "trash.cannot_place": "원본 폴더에 결과를 저장하지 못했어요", + "trash.changed": "변환한 뒤에 바뀌었어요", "notice.empty_spreadsheet_pages_removed": "스프레드시트의 빈 페이지를 제거했어요", "notice.ocr_has_text": "모든 페이지에 이미 텍스트가 있어서 그대로 복사했어요", "notice.live_photo_pair": "같은 이름의 사진과 MOV로 저장했어요. 두 파일을 함께 가져오면(iCloud 사진, AirDrop, Mac의 사진 앱) 라이브 포토가 돼요", diff --git a/src/Filee.App/Assets/i18n/ne.json b/src/Filee.App/Assets/i18n/ne.json index a9a85890..8b9d011a 100644 --- a/src/Filee.App/Assets/i18n/ne.json +++ b/src/Filee.App/Assets/i18n/ne.json @@ -44,6 +44,11 @@ "home.clear_history": "खाली गर्नुहोस्", "home.files": "{0} फाइलहरू", "home.failed_files": "{0} असफल", + "home.undo": "पूर्ववत गर्नुहोस्", + "home.undo_hint": "नतिजाहरूलाई रिसाइकल बिन / ट्र्यासमा सार्नुहोस्", + "home.undone": "पूर्ववत गरियो: नतिजाहरू रिसाइकल बिन / ट्र्यासमा छन्", + "home.undone_original": "पूर्ववत गरियो: नतिजाहरू रिसाइकल बिन / ट्र्यासमा छन्, र तिनले बदलेका मूल फाइलहरू पनि त्यहीँ छन्", + "home.undo_failed": "{0} लाई रिसाइकल बिन / ट्र्यासमा सार्न सकिएन: {1}", "donut.center_drag": "फाइलहरू यहाँ ल्याउनुहोस्", "donut.files_same": "{0} × {1}", "donut.files_mixed": "{0} फाइलहरू", @@ -119,6 +124,7 @@ "trash.no_folder": "ट्र्यास फोल्डर छैन", "trash.failed": "यसलाई रिसाइकल बिन / ट्र्यासमा सार्न सकिएन", "trash.cannot_place": "नतिजा मूल फाइलको फोल्डरमा सेभ गर्न सकिएन", + "trash.changed": "रूपान्तरणपछि यसलाई परिवर्तन गरिएको छ", "notice.ocr_has_text": "हरेक पृष्ठमा पहिले नै पाठ छ, त्यसैले जस्तो छ त्यस्तै प्रतिलिपि गरियो", "notice.empty_spreadsheet_pages_removed": "स्प्रेडसिटका खाली पृष्ठहरू हटाइए", "notice.live_photo_pair": "एउटै नामको फोटो र MOV का रूपमा सुरक्षित गरियो। लाइभ फोटो पाउन दुवैलाई सँगै आयात गर्नुहोस् (iCloud Photos, AirDrop वा Mac मा Photos)", diff --git a/src/Filee.App/Assets/i18n/pl.json b/src/Filee.App/Assets/i18n/pl.json index 72f4aa02..8aa702f2 100644 --- a/src/Filee.App/Assets/i18n/pl.json +++ b/src/Filee.App/Assets/i18n/pl.json @@ -47,6 +47,11 @@ "home.clear_history": "Wyczyść", "home.files": "Pliki: {0}", "home.failed_files": "Błędy: {0}", + "home.undo": "Cofnij", + "home.undo_hint": "Przenieś wyniki do Kosza", + "home.undone": "Cofnięto: wyniki są w Koszu", + "home.undone_original": "Cofnięto: wyniki są w Koszu, tak jak oryginały, które zastąpiły", + "home.undo_failed": "Nie udało się przenieść {0} do Kosza: {1}", "donut.center_drag": "Przenieś pliki tutaj", "donut.files_same": "{0} × {1}", @@ -125,6 +130,7 @@ "trash.no_folder": "nie ma folderu Kosza", "trash.failed": "nie udało się przenieść go do Kosza", "trash.cannot_place": "nie udało się zapisać wyniku w folderze oryginału", + "trash.changed": "zmieniono go po konwersji", "notice.empty_spreadsheet_pages_removed": "Usunięto puste strony arkusza kalkulacyjnego", "notice.ocr_has_text": "Każda strona ma już tekst, więc skopiowano bez zmian", "notice.live_photo_pair": "Zapisano jako zdjęcie i plik MOV o tej samej nazwie. Zaimportuj je razem (Zdjęcia iCloud, AirDrop lub Zdjęcia na Macu), aby otrzymać Live Photo", diff --git a/src/Filee.App/Assets/i18n/pt-BR.json b/src/Filee.App/Assets/i18n/pt-BR.json index 75099813..b15db430 100644 --- a/src/Filee.App/Assets/i18n/pt-BR.json +++ b/src/Filee.App/Assets/i18n/pt-BR.json @@ -47,6 +47,11 @@ "home.clear_history": "Limpar", "home.files": "{0} arquivos", "home.failed_files": "{0} falharam", + "home.undo": "Desfazer", + "home.undo_hint": "Mover os resultados para a Lixeira", + "home.undone": "Desfeito: os resultados estão na Lixeira", + "home.undone_original": "Desfeito: os resultados estão na Lixeira, assim como os originais que eles substituíram", + "home.undo_failed": "Não foi possível mover {0} para a Lixeira: {1}", "donut.center_drag": "Traga os arquivos para cá", "donut.files_same": "{0} × {1}", @@ -125,6 +130,7 @@ "trash.no_folder": "não há pasta de Lixeira", "trash.failed": "não foi possível movê-lo para a Lixeira", "trash.cannot_place": "não foi possível salvar o resultado na pasta do original", + "trash.changed": "ele foi alterado depois da conversão", "notice.empty_spreadsheet_pages_removed": "As páginas vazias da planilha foram removidas", "notice.ocr_has_text": "Todas as páginas já têm texto, então foi copiado como está", "notice.live_photo_pair": "Salvo como uma foto e um MOV com o mesmo nome. Importe os dois juntos (Fotos do iCloud, AirDrop ou Fotos no Mac) para obter uma Live Photo", diff --git a/src/Filee.App/Assets/i18n/pt-PT.json b/src/Filee.App/Assets/i18n/pt-PT.json index e6ca7c15..e67c02ea 100644 --- a/src/Filee.App/Assets/i18n/pt-PT.json +++ b/src/Filee.App/Assets/i18n/pt-PT.json @@ -47,6 +47,11 @@ "home.clear_history": "Limpar", "home.files": "{0} ficheiros", "home.failed_files": "Falhas: {0}", + "home.undo": "Anular", + "home.undo_hint": "Mover os resultados para a Reciclagem ou para o Lixo", + "home.undone": "Anulado: os resultados estão na Reciclagem ou no Lixo", + "home.undone_original": "Anulado: os resultados estão na Reciclagem ou no Lixo, tal como os originais que substituíram", + "home.undo_failed": "Não foi possível mover {0} para a Reciclagem ou para o Lixo: {1}", "donut.center_drag": "Arrasta ficheiros para aqui", "donut.files_same": "{0} × {1}", @@ -125,6 +130,7 @@ "trash.no_folder": "não existe uma pasta de Lixo", "trash.failed": "não foi possível movê-lo para a Reciclagem ou para o Lixo", "trash.cannot_place": "não foi possível guardar o resultado na pasta do original", + "trash.changed": "foi alterado depois da conversão", "notice.empty_spreadsheet_pages_removed": "Foram removidas as páginas vazias das folhas de cálculo", "notice.ocr_has_text": "Todas as páginas já têm texto, pelo que o ficheiro foi copiado sem alterações", "notice.live_photo_pair": "Foi guardada uma fotografia e um MOV com o mesmo nome. Importa ambos em conjunto (Fotografias em iCloud, AirDrop ou Fotografias num Mac) para obteres uma Live Photo", diff --git a/src/Filee.App/Assets/i18n/ru.json b/src/Filee.App/Assets/i18n/ru.json index 29acdd1e..45dd75dd 100644 --- a/src/Filee.App/Assets/i18n/ru.json +++ b/src/Filee.App/Assets/i18n/ru.json @@ -47,6 +47,11 @@ "home.clear_history": "Очистить", "home.files": "Файлов: {0}", "home.failed_files": "Ошибок: {0}", + "home.undo": "Отменить", + "home.undo_hint": "Переместить результаты в Корзину", + "home.undone": "Отменено: результаты в Корзине", + "home.undone_original": "Отменено: результаты в Корзине, как и оригиналы, которые они заменили", + "home.undo_failed": "Не удалось переместить {0} в Корзину: {1}", "donut.center_drag": "Перетащите сюда", "donut.files_same": "{0} × {1}", @@ -125,6 +130,7 @@ "trash.no_folder": "нет папки Корзины", "trash.failed": "не удалось переместить его в Корзину", "trash.cannot_place": "не удалось сохранить результат в папке оригинала", + "trash.changed": "он изменился после преобразования", "notice.empty_spreadsheet_pages_removed": "Пустые страницы таблицы удалены", "notice.ocr_has_text": "На всех страницах уже есть текст, поэтому файл скопирован как есть", "notice.live_photo_pair": "Сохранено как фото и MOV с одинаковым именем. Импортируйте их вместе (Фото iCloud, AirDrop или «Фото» на Mac), чтобы получить Live Photo", diff --git a/src/Filee.App/Assets/i18n/th.json b/src/Filee.App/Assets/i18n/th.json index 8c419e6b..d6d11bc7 100644 --- a/src/Filee.App/Assets/i18n/th.json +++ b/src/Filee.App/Assets/i18n/th.json @@ -44,6 +44,11 @@ "home.clear_history": "ล้างประวัติ", "home.files": "{0} ไฟล์", "home.failed_files": "ล้มเหลว {0} ไฟล์", + "home.undo": "เลิกทำ", + "home.undo_hint": "ย้ายผลลัพธ์ไปที่ถังรีไซเคิล / ถังขยะ", + "home.undone": "เลิกทำแล้ว: ผลลัพธ์อยู่ในถังรีไซเคิล / ถังขยะ", + "home.undone_original": "เลิกทำแล้ว: ผลลัพธ์อยู่ในถังรีไซเคิล / ถังขยะ และต้นฉบับที่ถูกแทนที่ก็อยู่ที่นั่นด้วย", + "home.undo_failed": "ย้าย {0} ไปที่ถังรีไซเคิล / ถังขยะไม่ได้: {1}", "donut.center_drag": "ลากไฟล์มาที่นี่", "donut.files_same": "{0} × {1}", "donut.files_mixed": "{0} ไฟล์", @@ -119,6 +124,7 @@ "trash.no_folder": "ไม่มีโฟลเดอร์ถังขยะ", "trash.failed": "ย้ายไปที่ถังรีไซเคิล / ถังขยะไม่ได้", "trash.cannot_place": "บันทึกผลลัพธ์ในโฟลเดอร์ของไฟล์ต้นฉบับไม่ได้", + "trash.changed": "ไฟล์ถูกแก้ไขหลังการแปลง", "notice.ocr_has_text": "ทุกหน้ามีข้อความอยู่แล้ว จึงคัดลอกไฟล์ตามเดิม", "notice.empty_spreadsheet_pages_removed": "ลบหน้าว่างของสเปรดชีตออกแล้ว", "notice.live_photo_pair": "บันทึกเป็นรูปภาพและไฟล์ MOV ที่มีชื่อเดียวกัน นำเข้าทั้งสองไฟล์พร้อมกัน (ผ่านรูปภาพ iCloud, AirDrop หรือ Photos บน Mac) เพื่อใช้งานเป็น Live Photo", diff --git a/src/Filee.App/Assets/i18n/tr.json b/src/Filee.App/Assets/i18n/tr.json index 62a8e5e1..87babf8f 100644 --- a/src/Filee.App/Assets/i18n/tr.json +++ b/src/Filee.App/Assets/i18n/tr.json @@ -44,6 +44,11 @@ "home.clear_history": "Temizle", "home.files": "{0} dosya", "home.failed_files": "{0} başarısız", + "home.undo": "Geri al", + "home.undo_hint": "Sonuçları Geri Dönüşüm Kutusu'na / Çöp Sepeti'ne taşı", + "home.undone": "Geri alındı: sonuçlar Geri Dönüşüm Kutusu'nda / Çöp Sepeti'nde", + "home.undone_original": "Geri alındı: sonuçlar ve yerini aldıkları orijinaller Geri Dönüşüm Kutusu'nda / Çöp Sepeti'nde", + "home.undo_failed": "{0} Geri Dönüşüm Kutusu'na / Çöp Sepeti'ne taşınamadı: {1}", "donut.center_drag": "Dosyaları buraya getirin", "donut.files_same": "{0} × {1}", "donut.files_mixed": "{0} dosya", @@ -119,6 +124,7 @@ "trash.no_folder": "Çöp Sepeti klasörü yok", "trash.failed": "Geri Dönüşüm Kutusu'na / Çöp Sepeti'ne taşınamadı", "trash.cannot_place": "sonuç özgün dosyanın klasörüne kaydedilemedi", + "trash.changed": "dönüştürmeden sonra değiştirildi", "notice.empty_spreadsheet_pages_removed": "Elektronik tablodaki boş sayfalar kaldırıldı", "notice.ocr_has_text": "Her sayfada zaten metin olduğu için dosya olduğu gibi kopyalandı", "notice.live_photo_pair": "Aynı adlı fotoğraf ve MOV dosyası olarak kaydedildi. Live Photo elde etmek için ikisini birlikte içe aktarın (iCloud Fotoğrafları, AirDrop veya Mac'teki Fotoğraflar ile)", diff --git a/src/Filee.App/Assets/i18n/zh-CN.json b/src/Filee.App/Assets/i18n/zh-CN.json index 340de83b..4ff4f9ac 100644 --- a/src/Filee.App/Assets/i18n/zh-CN.json +++ b/src/Filee.App/Assets/i18n/zh-CN.json @@ -47,6 +47,11 @@ "home.clear_history": "清除", "home.files": "{0} 个文件", "home.failed_files": "{0} 个失败", + "home.undo": "撤销", + "home.undo_hint": "将结果移到回收站/废纸篓", + "home.undone": "已撤销:结果已在回收站/废纸篓中", + "home.undone_original": "已撤销:结果已在回收站/废纸篓中,被替换的原文件也在那里", + "home.undo_failed": "无法将 {0} 移到回收站/废纸篓:{1}", "donut.center_drag": "把文件拖到这里", "donut.files_same": "{0} 个 {1}", @@ -125,6 +130,7 @@ "trash.no_folder": "没有废纸篓文件夹", "trash.failed": "无法移到回收站/废纸篓", "trash.cannot_place": "无法将结果保存到原文件所在的文件夹", + "trash.changed": "转换后它被修改过", "notice.empty_spreadsheet_pages_removed": "已移除电子表格中的空白页面", "notice.ocr_has_text": "每页都已有文字,已原样复制", "notice.live_photo_pair": "已保存为同名的照片和 MOV。将两者一起导入(iCloud 照片、隔空投送或 Mac 上的“照片”)即可得到实况照片", diff --git a/src/Filee.App/Assets/i18n/zh-TW.json b/src/Filee.App/Assets/i18n/zh-TW.json index ee508a74..d9f1c979 100644 --- a/src/Filee.App/Assets/i18n/zh-TW.json +++ b/src/Filee.App/Assets/i18n/zh-TW.json @@ -47,6 +47,11 @@ "home.clear_history": "清除", "home.files": "{0} 個檔案", "home.failed_files": "{0} 個失敗", + "home.undo": "復原", + "home.undo_hint": "將結果移到資源回收筒/垃圾桶", + "home.undone": "已復原:結果已在資源回收筒/垃圾桶中", + "home.undone_original": "已復原:結果已在資源回收筒/垃圾桶中,被取代的原始檔也在那裡", + "home.undo_failed": "無法將 {0} 移到資源回收筒/垃圾桶:{1}", "donut.center_drag": "把檔案拖到這裡", "donut.files_same": "{0} 個 {1}", @@ -125,6 +130,7 @@ "trash.no_folder": "沒有垃圾桶資料夾", "trash.failed": "無法移到資源回收筒/垃圾桶", "trash.cannot_place": "無法將結果儲存到原始檔案所在的資料夾", + "trash.changed": "轉換後已被修改", "notice.empty_spreadsheet_pages_removed": "已移除試算表中的空白頁面", "notice.ocr_has_text": "每頁都已有文字,已原樣複製", "notice.live_photo_pair": "已儲存為同名的照片和 MOV。將兩者一起匯入(iCloud 照片、隔空投送或 Mac 上的「照片」)即可得到原況照片", diff --git a/src/Filee.App/Styles/Icons.axaml b/src/Filee.App/Styles/Icons.axaml index 21ca4ad7..c8c0588b 100644 --- a/src/Filee.App/Styles/Icons.axaml +++ b/src/Filee.App/Styles/Icons.axaml @@ -33,6 +33,7 @@ M12,2A10,10 0 0,0 2,12C2,16.42 4.87,20.17 8.84,21.5C9.34,21.58 9.5,21.27 9.5,21C9.5,20.77 9.5,20.14 9.5,19.31C6.73,19.91 6.14,17.97 6.14,17.97C5.68,16.81 5.03,16.5 5.03,16.5C4.12,15.88 5.1,15.9 5.1,15.9C6.1,15.97 6.63,16.93 6.63,16.93C7.5,18.45 8.97,18 9.54,17.76C9.63,17.11 9.89,16.67 10.17,16.42C7.95,16.17 5.62,15.31 5.62,11.5C5.62,10.39 6,9.5 6.65,8.79C6.55,8.54 6.2,7.5 6.75,6.15C6.75,6.15 7.59,5.88 9.5,7.17C10.29,6.95 11.15,6.84 12,6.84C12.85,6.84 13.71,6.95 14.5,7.17C16.41,5.88 17.25,6.15 17.25,6.15C17.8,7.5 17.45,8.54 17.35,8.79C18,9.5 18.38,10.39 18.38,11.5C18.38,15.32 16.04,16.16 13.81,16.41C14.17,16.72 14.5,17.33 14.5,18.26C14.5,19.6 14.5,20.68 14.5,21C14.5,21.27 14.66,21.59 15.17,21.5C19.14,20.16 22,16.42 22,12A10,10 0 0,0 12,2Z M12,21.35L10.55,20.03C5.4,15.36 2,12.27 2,8.5C2,5.41 4.42,3 7.5,3C9.24,3 10.91,3.81 12,5.08C13.09,3.81 14.76,3 16.5,3C19.58,3 22,5.41 22,8.5C22,12.27 18.6,15.36 13.45,20.03L12,21.35Z M17.65,6.35C16.2,4.9 14.21,4 12,4A8,8 0 0,0 4,12A8,8 0 0,0 12,20C15.73,20 18.84,17.45 19.73,14H17.65C16.83,16.33 14.61,18 12,18A6,6 0 0,1 6,12A6,6 0 0,1 12,6C13.66,6 15.14,6.69 16.22,7.78L13,11H20V4L17.65,6.35Z + M12.5,8C9.85,8 7.45,9 5.6,10.6L2,7V16H11L7.38,12.38C8.77,11.22 10.54,10.5 12.5,10.5C16.04,10.5 19.05,12.81 20.1,16L22.47,15.22C21.08,11.03 17.15,8 12.5,8Z M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2M12,7A5,5 0 0,1 17,12A5,5 0 0,1 12,17A5,5 0 0,1 7,12A5,5 0 0,1 12,7Z M7,17V1H5V5H1V7H5V17A2,2 0 0,0 7,19H17V23H19V19H23V17M17,15H19V7C19,5.89 18.1,5 17,5H9V7H17V15Z M9.64,7.64C9.87,7.14 10,6.59 10,6A4,4 0 0,0 6,2A4,4 0 0,0 2,6A4,4 0 0,0 6,10C6.59,10 7.14,9.87 7.64,9.64L10,12L7.64,14.36C7.14,14.13 6.59,14 6,14A4,4 0 0,0 2,18A4,4 0 0,0 6,22A4,4 0 0,0 10,18C10,17.41 9.87,16.86 9.64,16.36L12,14L19,21H22V20L9.64,7.64M6,8A2,2 0 0,1 4,6A2,2 0 0,1 6,4A2,2 0 0,1 8,6A2,2 0 0,1 6,8M6,20A2,2 0 0,1 4,18A2,2 0 0,1 6,16A2,2 0 0,1 8,18A2,2 0 0,1 6,20M19,3L13,9L15,11L22,4V3H19Z diff --git a/src/Filee.App/ViewModels/Pages/HomePageViewModel.cs b/src/Filee.App/ViewModels/Pages/HomePageViewModel.cs index 447facf1..663c6bfd 100644 --- a/src/Filee.App/ViewModels/Pages/HomePageViewModel.cs +++ b/src/Filee.App/ViewModels/Pages/HomePageViewModel.cs @@ -18,17 +18,22 @@ namespace Filee.App.ViewModels.Pages; public sealed partial class HistoryItemViewModel : ObservableObject { private readonly HistoryEntry _entry; + private readonly ILocalizer _loc; private readonly IPlatformServices _platform; private readonly ConversionService? _conversions; + private readonly UserDataStore? _store; /// The first output still on disk (the one the buttons open), or null. private readonly string? _output; - public HistoryItemViewModel(HistoryEntry entry, ILocalizer loc, IPlatformServices platform, ConversionService? conversions = null) + public HistoryItemViewModel(HistoryEntry entry, ILocalizer loc, IPlatformServices platform, ConversionService? conversions = null, + UserDataStore? store = null) { _entry = entry; + _loc = loc; _platform = platform; _conversions = conversions; + _store = store; Title = entry.PresetName; Subtitle = entry.Sources.Count == 1 ? Path.GetFileName(entry.Sources[0]) : loc.Format("home.files", entry.Sources.Count); Time = entry.FinishedAt.Date == DateTime.Today ? entry.FinishedAt.ToString("t") : entry.FinishedAt.ToString("d"); @@ -52,8 +57,17 @@ public HistoryItemViewModel(HistoryEntry entry, ILocalizer loc, IPlatformService ThumbnailSource = picture is not null && HistoryThumbnails.CanShow(picture) ? picture : null; // Only entries that remember their preset (Filee 1.8 and later) and still have a failed file to convert. CanRetry = conversions is not null && entry.Preset is not null && entry.Failures.Any(f => ConversionService.Exists(f.Source)); + CanUndo = store is not null && UndoLeft(); + UndoneText = entry.Undone ? loc[entry.OriginalsInTrash ? "home.undone_original" : "home.undone"] : ""; } + /// + /// Undo (#553) is offered while the results not moved yet are all as the job left them, so a file changed since is + /// never moved; after an Undo that stopped half-way, for the ones it didn't get to. + /// + private bool UndoLeft() => + !_entry.Undone && _entry.Undoable.Where(o => !o.Trashed).ToList() is { Count: > 0 } left && left.All(o => o.Unchanged()); + public string Title { get; } public string Subtitle { get; } public string Time { get; } @@ -101,6 +115,62 @@ private void Retry() _conversions.Retry(_entry.Failures.Select(f => f.Source), _entry.Preset, _entry.WatchRuleId); } + [ObservableProperty] private bool _canUndo; + + /// "Undone: the results are in the Recycle Bin / Trash", or empty. + public string UndoneText { get; } + + public bool IsUndone => UndoneText.Length > 0; + + /// Why a result couldn't be moved to the Recycle Bin / Trash, or empty. + [ObservableProperty, NotifyPropertyChangedFor(nameof(HasUndoError))] private string _undoError = ""; + + public bool HasUndoError => UndoError.Length > 0; + + /// + /// Moves the job's results to the Recycle Bin / Trash, off the UI thread (Windows' Recycle Bin takes a moment per + /// file); the button is disabled meanwhile. Every result is checked first, so a changed one stops it with nothing + /// moved. Each result moved is saved as such, so an Undo the Trash stops half-way can be tried again for the rest. + /// "Replace the original" sent the originals there already: they stay, and the card says so. + /// + [RelayCommand] + private async Task UndoAsync() + { + if (!CanUndo || _store is null) + return; + UndoError = ""; + var left = _entry.Undoable.Where(o => !o.Trashed).ToList(); + if (left.FirstOrDefault(o => !o.Unchanged()) is { } changed) + { + Refused(changed, new TrashRefusal("trash.changed")); + return; + } + var refused = await Task.Run(() => + { + foreach (var output in left) + { + if (_platform.MoveToTrash(output.Path) is { } refusal) + return (output, refusal); + output.Trashed = true; + } + return default((HistoryOutput, TrashRefusal)?); + }); + if (refused is { } stop) + { + _store.SaveHistory(notify: false); // the moved ones stay moved; this card says why it stopped + Refused(stop.Item1, stop.Item2); + return; + } + _entry.Undone = true; + _store.SaveHistory(); + } + + private void Refused(HistoryOutput output, TrashRefusal refusal) + { + UndoError = _loc.Format("home.undo_failed", Path.GetFileName(output.Path), _loc[refusal.ReasonKey]); + CanUndo = UndoLeft(); + } + [RelayCommand] private void OpenFolder() { @@ -223,7 +293,7 @@ private void Reload() .ToList(); History.Clear(); foreach (var entry in entries) - History.Add(new HistoryItemViewModel(entry, _loc, _platform, _conversions)); + History.Add(new HistoryItemViewModel(entry, _loc, _platform, _conversions, _store)); IsEmpty = _store.History.Count == 0; NoMatches = !IsEmpty && History.Count == 0; LoadThumbnails(); diff --git a/src/Filee.App/Views/Pages/HomePage.axaml b/src/Filee.App/Views/Pages/HomePage.axaml index a83a3d28..aae555da 100644 --- a/src/Filee.App/Views/Pages/HomePage.axaml +++ b/src/Filee.App/Views/Pages/HomePage.axaml @@ -113,6 +113,13 @@ + + @@ -156,6 +163,9 @@ + + +