diff --git a/docs/ENGINES.md b/docs/ENGINES.md index 1428cabf3..d2848db9e 100644 --- a/docs/ENGINES.md +++ b/docs/ENGINES.md @@ -99,6 +99,14 @@ they can be installed or removed later in Settings → *Engines*. A conversion t name the oldest macOS it runs on (`minimumMacOS`); an older Mac isn't offered it. - `EngineInstaller` verifies the SHA-256 before unpacking and unpacks into a staging folder that replaces the engine folder only when complete. Redirects to mirrors (even plain HTTP) are followed, because the hash decides. +- Without internet (#447) the same downloads can come from a folder: the card's *Offline* menu saves them on a + computer with internet (*Save the files for another computer…*, `filee engines download -o `), copies + their links, and installs them (*Install from downloaded files…*, `filee engines install --from `). A + file counts as a component's when it has the exact size engines.json pins (its download's name breaks a tie), and + only the top level of a folder is looked at. Every file is copied into `.downloads` and checked against its + SHA-256 before the first one is unpacked, so a missing or wrong file leaves the package as it was. Only the + downloads are taken, never an installed engine folder: an unpacked and trimmed folder has nothing pinned to check + it against. The other computer needs the same Filee version (the same engines.json). - Engines go to `%LOCALAPPDATA%\Filee\engines`: outside the app folder, so updates keep them, and inside Filee's install root, so uninstalling removes them. - LibreOffice and calibre come as MSIs and are unpacked with an administrative install (`msiexec /a`): files only, diff --git a/src/Filee.App/Assets/i18n/ar.json b/src/Filee.App/Assets/i18n/ar.json index 5c5f3a011..ba08af29f 100644 --- a/src/Filee.App/Assets/i18n/ar.json +++ b/src/Filee.App/Assets/i18n/ar.json @@ -130,6 +130,8 @@ "error.rhwp_timeout_calibre": "لم يتمكن rhwp من إكمال هذا المستند الطويل في الوقت المحدد. للكتب الإلكترونية، انقل Calibre فوق محرك كتابة HWPX من الإعدادات ← المحركات، ليُنشئ Calibre ملف PDF بسرعة أكبر بكثير", "error.engine_stalled": "توقف المحرك عن الاستجابة: لم يحرز أي تقدم لفترة طويلة، لذا تم إيقافه", "error.engine_busy": "نسخة أخرى من Filee (التطبيق أو سطر الأوامر أو نسخة ثانية) تثبّت هذا المحرك أو تزيله الآن. أعد المحاولة بعد انتهائها.", + "error.engine_files_missing": "لم تُختر كل ملفات المحرك، أو بعضها لإصدار آخر من Filee. يحتاج إلى هذه الملفات", + "error.engine_file_mismatch": "هذا الملف ليس الملف الذي ينزّله Filee لهذا المحرك: إنه تالف أو إصدار مختلف", "error.needs_shaping": "يحتاج هذا النص إلى LibreOffice لتحويله بصورة صحيحة. ثبّته من الإعدادات ← المحركات", "error.runtime_missing": "أحد ملفات وقت تشغيل Microsoft Visual C++ التي يحتاجها هذا المحرك مفقود أو قديم. حدّث Filee أو أعد تثبيته، أو ثبّت Microsoft Visual C++ Redistributable ‏(x64)", "error.conversion_failed": "أبلغ المحرك عن خطأ", @@ -1274,6 +1276,17 @@ "engines.state.unpacking": "جارٍ التثبيت…", "engines.state.installed": "مثبّت", "engines.state.failed": "فشل: {0}", + "engines.offline": "دون اتصال", + "engines.offline_hint": "لا يوجد إنترنت هنا؟ ثبّت من ملفات نُزّلت على حاسوب آخر، أو احفظ الملفات هناك لهذا الحاسوب.", + "engines.install_from_files": "التثبيت من ملفات منزّلة…", + "engines.install_from_files_title": "اختر الملفات المنزّلة لـ {0}", + "engines.save_files": "حفظ الملفات لحاسوب آخر…", + "engines.save_files_title": "اختر مكان حفظ ملفات {0}", + "engines.save_files_done": "ملفات {0} موجودة في {1}.\nانسخها إلى الحاسوب الآخر واختر هناك دون اتصال ← التثبيت من ملفات منزّلة. يحتاج إلى الإصدار نفسه من Filee.", + "engines.save_files_failed": "تعذّر حفظ الملفات: {0}", + "engines.copy_links": "نسخ روابط التنزيل", + "engines.links_copied": "روابط التنزيل في الحافظة. نزّل الملفات على حاسوب متصل بالإنترنت، ثم اختر هنا دون اتصال ← التثبيت من ملفات منزّلة.", + "engines.state.copying": "جارٍ النسخ {0}%", "about.title": "حول التطبيق", "about.updates": "التحديثات", "common.search": "بحث", diff --git a/src/Filee.App/Assets/i18n/bn-BD.json b/src/Filee.App/Assets/i18n/bn-BD.json index a56fc75a5..4a4c886f9 100644 --- a/src/Filee.App/Assets/i18n/bn-BD.json +++ b/src/Filee.App/Assets/i18n/bn-BD.json @@ -129,6 +129,8 @@ "error.rhwp_timeout_calibre": "rhwp এই দীর্ঘ ডকুমেন্টটি যথাসময়ে শেষ করতে পারেনি। ই-বুকের ক্ষেত্রে, সেটিংস → ইঞ্জিন-এ HWPX রাইটারের ওপরে Calibre নিয়ে আসুন, Calibre অনেক দ্রুত পিডিএফ তৈরি করবে", "error.engine_stalled": "ইঞ্জিন সাড়া দেওয়া বন্ধ করে দিয়েছে: দীর্ঘ সময় ধরে কোনো অগ্রগতি দেখা যায়নি, তাই এটি বন্ধ করা হয়েছে", "error.engine_busy": "আরেকটি ফাইলি (অ্যাপ, কমান্ড লাইন বা দ্বিতীয় কোনো কপি) এই ইঞ্জিন ইনস্টল বা অপসারণ করছে। সেটি শেষ হলে আবার চেষ্টা করুন।", + "error.engine_files_missing": "ইঞ্জিনের সব ফাইল বেছে নেওয়া হয়নি, অথবা কিছু ফাইল Filee-এর অন্য সংস্করণের। এই ফাইলগুলো দরকার", + "error.engine_file_mismatch": "এই ফাইলটি Filee এই ইঞ্জিনের জন্য যে ফাইল ডাউনলোড করে সেটি নয়: এটি নষ্ট বা অন্য সংস্করণের", "error.needs_shaping": "সঠিকভাবে রূপান্তর করতে এই স্ক্রিপ্টের LibreOffice প্রয়োজন। সেটিংস → ইঞ্জিন-এ এটি ইনস্টল করুন", "error.runtime_missing": "এই ইঞ্জিনের প্রয়োজনীয় মাইক্রোসফট ভিসুয়াল সি++ রানটাইম ফাইল অনুপস্থিত বা পুরোনো। ফাইলি আপডেট বা পুনরায় ইনস্টল করুন, অথবা মাইক্রোসফট ভিসুয়াল সি++ Redistributable (x64) ইনস্টল করুন", "error.conversion_failed": "ইঞ্জিন একটি ত্রুটি জানিয়েছে", @@ -1273,6 +1275,17 @@ "engines.state.unpacking": "ইনস্টল হচ্ছে…", "engines.state.installed": "ইনস্টল করা হয়েছে", "engines.state.failed": "ব্যর্থ হয়েছে: {0}", + "engines.offline": "অফলাইন", + "engines.offline_hint": "এখানে ইন্টারনেট নেই? অন্য কম্পিউটারে ডাউনলোড করা ফাইল থেকে ইনস্টল করুন, অথবা সেখানে এই কম্পিউটারের জন্য ফাইলগুলো সংরক্ষণ করুন।", + "engines.install_from_files": "ডাউনলোড করা ফাইল থেকে ইনস্টল করুন…", + "engines.install_from_files_title": "{0}-এর ডাউনলোড করা ফাইলগুলো বেছে নিন", + "engines.save_files": "অন্য কম্পিউটারের জন্য ফাইল সংরক্ষণ করুন…", + "engines.save_files_title": "{0}-এর ফাইলগুলো কোথায় সংরক্ষণ হবে বেছে নিন", + "engines.save_files_done": "{0}-এর ফাইলগুলো {1}-এ আছে।\nসেগুলো অন্য কম্পিউটারে কপি করুন এবং সেখানে অফলাইন → ডাউনলোড করা ফাইল থেকে ইনস্টল করুন বেছে নিন। সেখানে Filee-এর একই সংস্করণ লাগবে।", + "engines.save_files_failed": "ফাইলগুলো সংরক্ষণ করা যায়নি: {0}", + "engines.copy_links": "ডাউনলোড লিংক কপি করুন", + "engines.links_copied": "ডাউনলোড লিংকগুলো ক্লিপবোর্ডে কপি হয়েছে। ইন্টারনেট আছে এমন কম্পিউটারে ফাইলগুলো ডাউনলোড করুন, তারপর এখানে অফলাইন → ডাউনলোড করা ফাইল থেকে ইনস্টল করুন বেছে নিন।", + "engines.state.copying": "{0}% কপি হচ্ছে", "about.title": "পরিচিতি", "about.updates": "আপডেট", "common.search": "অনুসন্ধান", diff --git a/src/Filee.App/Assets/i18n/de.json b/src/Filee.App/Assets/i18n/de.json index 4fca9a9e6..4cdeca362 100644 --- a/src/Filee.App/Assets/i18n/de.json +++ b/src/Filee.App/Assets/i18n/de.json @@ -130,6 +130,8 @@ "error.rhwp_timeout_calibre": "rhwp konnte dieses lange Dokument nicht rechtzeitig fertigstellen. Verschiebe bei E-Books Calibre unter Einstellungen → Module über den HWPX-Writer. Calibre erstellt die PDF deutlich schneller", "error.engine_stalled": "Das Modul reagiert nicht mehr: Es kam lange nicht voran und wurde beendet", "error.engine_busy": "Ein anderes Filee (die App, die Befehlszeile oder eine zweite Kopie) installiert oder entfernt dieses Modul gerade. Versuche es erneut, wenn es fertig ist.", + "error.engine_files_missing": "Nicht alle Dateien des Moduls wurden ausgewählt, oder einige gehören zu einer anderen Filee-Version. Es braucht diese Dateien", + "error.engine_file_mismatch": "Diese Datei ist nicht die, die Filee für dieses Modul herunterlädt: Sie ist beschädigt oder eine andere Version", "error.needs_shaping": "Diese Schrift benötigt LibreOffice für eine korrekte Konvertierung. Installiere es unter Einstellungen → Module", "error.runtime_missing": "Eine von diesem Modul benötigte Microsoft-Visual-C++-Laufzeitdatei fehlt oder ist veraltet. Aktualisiere Filee, installiere es neu oder installiere Microsoft Visual C++ Redistributable (x64)", "error.conversion_failed": "Das Modul hat einen Fehler gemeldet", @@ -1274,6 +1276,17 @@ "engines.state.unpacking": "Wird installiert…", "engines.state.installed": "Installiert", "engines.state.failed": "Fehlgeschlagen: {0}", + "engines.offline": "Offline", + "engines.offline_hint": "Kein Internet hier? Installiere aus Dateien, die auf einem anderen Computer heruntergeladen wurden, oder speichere sie dort für diesen.", + "engines.install_from_files": "Aus heruntergeladenen Dateien installieren…", + "engines.install_from_files_title": "Wähle die heruntergeladenen Dateien von {0}", + "engines.save_files": "Dateien für einen anderen Computer speichern…", + "engines.save_files_title": "Wähle, wo die Dateien von {0} gespeichert werden", + "engines.save_files_done": "Die Dateien von {0} liegen in {1}.\nKopiere sie auf den anderen Computer und wähle dort Offline → Aus heruntergeladenen Dateien installieren. Er braucht dieselbe Filee-Version.", + "engines.save_files_failed": "Die Dateien konnten nicht gespeichert werden: {0}", + "engines.copy_links": "Download-Links kopieren", + "engines.links_copied": "Die Download-Links sind in der Zwischenablage. Lade die Dateien auf einem Computer mit Internet herunter und wähle dann hier Offline → Aus heruntergeladenen Dateien installieren.", + "engines.state.copying": "Kopieren: {0}%", "about.title": "Über Filee", "about.updates": "Updates", "common.search": "Suchen", diff --git a/src/Filee.App/Assets/i18n/en.json b/src/Filee.App/Assets/i18n/en.json index 284b83b1f..a22207cff 100644 --- a/src/Filee.App/Assets/i18n/en.json +++ b/src/Filee.App/Assets/i18n/en.json @@ -136,6 +136,8 @@ "error.rhwp_timeout_calibre": "rhwp couldn't finish this long document in time. For an e-book, move Calibre above the HWPX writer in Settings → Engines, and Calibre makes the PDF much faster", "error.engine_stalled": "The engine stopped responding: it showed no progress for a long time, so it was stopped", "error.engine_busy": "Another Filee (the app, the command line or a second copy) is installing or removing this engine. Try again when it has finished.", + "error.engine_files_missing": "Not all of the engine's files were chosen, or some are for another version of Filee. It needs these files", + "error.engine_file_mismatch": "This file isn't the one Filee downloads for this engine: it's damaged or a different version", "error.needs_shaping": "This script needs LibreOffice to convert correctly. Install it in Settings → Engines", "error.runtime_missing": "A Microsoft Visual C++ runtime file this engine needs is missing or outdated. Update or reinstall Filee, or install the Microsoft Visual C++ Redistributable (x64)", "error.conversion_failed": "The engine reported an error", @@ -1291,6 +1293,17 @@ "engines.state.unpacking": "Installing…", "engines.state.installed": "Installed", "engines.state.failed": "Failed: {0}", + "engines.offline": "Offline", + "engines.offline_hint": "No internet here? Install from files downloaded on another computer, or save the files there for this one.", + "engines.install_from_files": "Install from downloaded files…", + "engines.install_from_files_title": "Choose the downloaded files of {0}", + "engines.save_files": "Save the files for another computer…", + "engines.save_files_title": "Choose where to save the files of {0}", + "engines.save_files_done": "The files of {0} are in {1}.\nCopy them to the other computer and choose Offline → Install from downloaded files there. It needs the same version of Filee.", + "engines.save_files_failed": "Couldn't save the files: {0}", + "engines.copy_links": "Copy download links", + "engines.links_copied": "The download links are on the clipboard. Download the files on a computer with internet, then choose Offline → Install from downloaded files here.", + "engines.state.copying": "Copying {0}%", "about.title": "About", "about.updates": "Updates", diff --git a/src/Filee.App/Assets/i18n/es.json b/src/Filee.App/Assets/i18n/es.json index 97448d7cb..bd32fc7e4 100644 --- a/src/Filee.App/Assets/i18n/es.json +++ b/src/Filee.App/Assets/i18n/es.json @@ -130,6 +130,8 @@ "error.rhwp_timeout_calibre": "rhwp no pudo terminar este documento largo a tiempo. Para un libro electrónico, mueve Calibre por encima del escritor HWPX en Ajustes → Motores; Calibre genera el PDF mucho más rápido", "error.engine_stalled": "El motor dejó de responder: no avanzó durante mucho tiempo y se detuvo", "error.engine_busy": "Otro Filee (la app, la línea de comandos u otra copia) está instalando o quitando este motor. Inténtalo otra vez cuando termine.", + "error.engine_files_missing": "No se eligieron todos los archivos del motor, o algunos son de otra versión de Filee. Necesita estos archivos", + "error.engine_file_mismatch": "Este archivo no es el que Filee descarga para este motor: está dañado o es otra versión", "error.needs_shaping": "Este sistema de escritura necesita LibreOffice para convertirse bien. Instálalo en Ajustes → Motores", "error.runtime_missing": "Falta un archivo del runtime de Microsoft Visual C++ que necesita este motor, o está desactualizado. Actualiza o reinstala Filee, o instala Microsoft Visual C++ Redistributable (x64)", "error.conversion_failed": "El motor devolvió un error", @@ -1274,6 +1276,17 @@ "engines.state.unpacking": "Instalando…", "engines.state.installed": "Instalado", "engines.state.failed": "Error: {0}", + "engines.offline": "Sin conexión", + "engines.offline_hint": "¿No hay internet aquí? Instala desde archivos descargados en otro equipo, o guarda allí los archivos para este.", + "engines.install_from_files": "Instalar desde archivos descargados…", + "engines.install_from_files_title": "Elige los archivos descargados de {0}", + "engines.save_files": "Guardar los archivos para otro equipo…", + "engines.save_files_title": "Elige dónde guardar los archivos de {0}", + "engines.save_files_done": "Los archivos de {0} están en {1}.\nCópialos al otro equipo y elige allí Sin conexión → Instalar desde archivos descargados. Necesita la misma versión de Filee.", + "engines.save_files_failed": "No se pudieron guardar los archivos: {0}", + "engines.copy_links": "Copiar enlaces de descarga", + "engines.links_copied": "Los enlaces de descarga están en el portapapeles. Descarga los archivos en un equipo con internet y luego elige aquí Sin conexión → Instalar desde archivos descargados.", + "engines.state.copying": "Copiando {0}%", "about.title": "Acerca de", "about.updates": "Actualizaciones", "common.search": "Buscar", diff --git a/src/Filee.App/Assets/i18n/fa.json b/src/Filee.App/Assets/i18n/fa.json index 74a11f8ec..1740e1e18 100644 --- a/src/Filee.App/Assets/i18n/fa.json +++ b/src/Filee.App/Assets/i18n/fa.json @@ -129,6 +129,8 @@ "error.rhwp_timeout_calibre": "موتور rhwp نتوانست این سند طولانی را به موقع تمام کند. برای کتاب‌های الکترونیکی، Calibre را در تنظیمات ← موتورها بالاتر از HWPX writer قرار دهید تا بسیار سریع‌تر PDF ساخته شود", "error.engine_stalled": "موتور پاسخ نمی‌دهد: برای مدت طولانی هیچ پیشرفتی نشان نداد، بنابراین متوقف شد", "error.engine_busy": "نسخه دیگری از Filee (برنامه، خط فرمان یا نسخه دوم) در حال نصب یا حذف این موتور است. پس از پایان آن مجدداً تلاش کنید.", + "error.engine_files_missing": "همه فایل‌های موتور انتخاب نشده‌اند، یا برخی برای نسخه دیگری از Filee هستند. این فایل‌ها لازم است", + "error.engine_file_mismatch": "این فایل همان فایلی نیست که Filee برای این موتور دانلود می‌کند: آسیب دیده یا نسخه دیگری است", "error.needs_shaping": "این خط نگارشی برای تبدیل صحیح به LibreOffice نیاز دارد. آن را در تنظیمات ← موتورها نصب کنید", "error.runtime_missing": "یک فایل پیش‌نیاز Microsoft Visual C++ مورد نیاز این موتور وجود ندارد یا قدیمی است. Filee را به‌روزرسانی یا مجدداً نصب کنید، یا Microsoft Visual C++ Redistributable (x64) را نصب نمایید", "error.conversion_failed": "موتور خطایی را گزارش کرد", @@ -1273,6 +1275,17 @@ "engines.state.unpacking": "در حال نصب…", "engines.state.installed": "نصب شد", "engines.state.failed": "ناموفق: {0}", + "engines.offline": "آفلاین", + "engines.offline_hint": "اینجا اینترنت ندارید؟ از فایل‌هایی که روی رایانه دیگری دانلود شده نصب کنید، یا فایل‌ها را آنجا برای این رایانه ذخیره کنید.", + "engines.install_from_files": "نصب از فایل‌های دانلودشده…", + "engines.install_from_files_title": "فایل‌های دانلودشده {0} را انتخاب کنید", + "engines.save_files": "ذخیره فایل‌ها برای رایانه دیگر…", + "engines.save_files_title": "محل ذخیره فایل‌های {0} را انتخاب کنید", + "engines.save_files_done": "فایل‌های {0} در {1} هستند.\nآن‌ها را به رایانه دیگر کپی کنید و آنجا آفلاین ← نصب از فایل‌های دانلودشده را انتخاب کنید. همان نسخه Filee لازم است.", + "engines.save_files_failed": "ذخیره فایل‌ها ممکن نشد: {0}", + "engines.copy_links": "کپی پیوندهای دانلود", + "engines.links_copied": "پیوندهای دانلود در کلیپ‌بورد است. فایل‌ها را روی رایانه‌ای با اینترنت دانلود کنید، سپس اینجا آفلاین ← نصب از فایل‌های دانلودشده را انتخاب کنید.", + "engines.state.copying": "در حال کپی {0}%", "about.title": "درباره", "about.updates": "به‌روزرسانی‌ها", "common.search": "جستجو", diff --git a/src/Filee.App/Assets/i18n/fr.json b/src/Filee.App/Assets/i18n/fr.json index c81882fde..9715208d8 100644 --- a/src/Filee.App/Assets/i18n/fr.json +++ b/src/Filee.App/Assets/i18n/fr.json @@ -136,6 +136,8 @@ "error.rhwp_timeout_calibre": "rhwp n'a pas pu terminer ce long document à temps. Pour un livre numérique, placez Calibre au-dessus du rédacteur HWPX dans Paramètres → Moteurs : Calibre produira le PDF bien plus vite", "error.engine_stalled": "Le moteur ne répond plus : il n'a pas progressé pendant longtemps et a été arrêté", "error.engine_busy": "Un autre Filee (l'application, la ligne de commande ou une autre copie) installe ou supprime ce moteur. Réessayez quand il aura terminé.", + "error.engine_files_missing": "Tous les fichiers du moteur n'ont pas été choisis, ou certains sont pour une autre version de Filee. Il lui faut ces fichiers", + "error.engine_file_mismatch": "Ce fichier n'est pas celui que Filee télécharge pour ce moteur : il est endommagé ou d'une autre version", "error.needs_shaping": "Cette écriture nécessite LibreOffice pour être convertie correctement. Installez-le dans Paramètres → Moteurs", "error.runtime_missing": "Un fichier du runtime Microsoft Visual C++ requis par ce moteur est manquant ou obsolète. Mettez à jour ou réinstallez Filee, ou installez Microsoft Visual C++ Redistributable (x64)", "error.conversion_failed": "Le moteur a signalé une erreur", @@ -1291,6 +1293,17 @@ "engines.state.unpacking": "Installation…", "engines.state.installed": "Installé", "engines.state.failed": "Échec : {0}", + "engines.offline": "Hors ligne", + "engines.offline_hint": "Pas d'internet ici ? Installez à partir de fichiers téléchargés sur un autre ordinateur, ou enregistrez-y les fichiers pour celui-ci.", + "engines.install_from_files": "Installer à partir de fichiers téléchargés…", + "engines.install_from_files_title": "Choisissez les fichiers téléchargés de {0}", + "engines.save_files": "Enregistrer les fichiers pour un autre ordinateur…", + "engines.save_files_title": "Choisissez où enregistrer les fichiers de {0}", + "engines.save_files_done": "Les fichiers de {0} sont dans {1}.\nCopiez-les sur l'autre ordinateur et choisissez-y Hors ligne → Installer à partir de fichiers téléchargés. Il lui faut la même version de Filee.", + "engines.save_files_failed": "Impossible d'enregistrer les fichiers : {0}", + "engines.copy_links": "Copier les liens de téléchargement", + "engines.links_copied": "Les liens de téléchargement sont dans le presse-papiers. Téléchargez les fichiers sur un ordinateur connecté à internet, puis choisissez ici Hors ligne → Installer à partir de fichiers téléchargés.", + "engines.state.copying": "Copie {0} %", "about.title": "À propos", "about.updates": "Mises à jour", diff --git a/src/Filee.App/Assets/i18n/hi.json b/src/Filee.App/Assets/i18n/hi.json index b1953da76..26a163cfd 100644 --- a/src/Filee.App/Assets/i18n/hi.json +++ b/src/Filee.App/Assets/i18n/hi.json @@ -130,6 +130,8 @@ "error.rhwp_timeout_calibre": "rhwp इस लंबे दस्तावेज़ को समय पर पूरा नहीं कर सका। ई-बुक के लिए, सेटिंग्स → इंजन में Calibre को HWPX writer के ऊपर ले जाएँ, तब Calibre PDF बहुत तेज़ी से बनाएगा", "error.engine_stalled": "इंजन ने जवाब देना बंद कर दिया: लंबे समय तक कोई प्रगति नहीं हुई, इसलिए इसे रोक दिया गया", "error.engine_busy": "कोई दूसरा Filee (ऐप, कमांड लाइन या दूसरी कॉपी) इस इंजन को इंस्टॉल कर रहा है या हटा रहा है। उसके पूरा होने के बाद फिर से कोशिश करें।", + "error.engine_files_missing": "इंजन की सभी फ़ाइलें नहीं चुनी गईं, या कुछ Filee के किसी दूसरे वर्ज़न की हैं। इन फ़ाइलों की ज़रूरत है", + "error.engine_file_mismatch": "यह वह फ़ाइल नहीं है जो Filee इस इंजन के लिए डाउनलोड करता है: यह खराब है या कोई दूसरा वर्ज़न है", "error.needs_shaping": "इस लिपि को सही ढंग से कन्वर्ट करने के लिए LibreOffice चाहिए। इसे सेटिंग्स → इंजन में इंस्टॉल करें", "error.runtime_missing": "इस इंजन के लिए ज़रूरी Microsoft Visual C++ रनटाइम फ़ाइल नहीं मिली या पुरानी है। Filee को अपडेट करें या फिर से इंस्टॉल करें, या Microsoft Visual C++ Redistributable (x64) इंस्टॉल करें", "error.conversion_failed": "इंजन ने एक त्रुटि बताई", @@ -1274,6 +1276,17 @@ "engines.state.unpacking": "इंस्टॉल हो रहा है…", "engines.state.installed": "इंस्टॉल हो गया", "engines.state.failed": "विफल: {0}", + "engines.offline": "ऑफ़लाइन", + "engines.offline_hint": "यहाँ इंटरनेट नहीं है? किसी दूसरे कंप्यूटर पर डाउनलोड की गई फ़ाइलों से इंस्टॉल करें, या वहाँ इस कंप्यूटर के लिए फ़ाइलें सेव करें।", + "engines.install_from_files": "डाउनलोड की गई फ़ाइलों से इंस्टॉल करें…", + "engines.install_from_files_title": "{0} की डाउनलोड की गई फ़ाइलें चुनें", + "engines.save_files": "दूसरे कंप्यूटर के लिए फ़ाइलें सेव करें…", + "engines.save_files_title": "चुनें कि {0} की फ़ाइलें कहाँ सेव हों", + "engines.save_files_done": "{0} की फ़ाइलें {1} में हैं।\nउन्हें दूसरे कंप्यूटर पर कॉपी करें और वहाँ ऑफ़लाइन → डाउनलोड की गई फ़ाइलों से इंस्टॉल करें चुनें। वहाँ Filee का यही वर्ज़न होना चाहिए।", + "engines.save_files_failed": "फ़ाइलें सेव नहीं हो सकीं: {0}", + "engines.copy_links": "डाउनलोड लिंक कॉपी करें", + "engines.links_copied": "डाउनलोड लिंक क्लिपबोर्ड पर कॉपी हो गए हैं। इंटरनेट वाले कंप्यूटर पर फ़ाइलें डाउनलोड करें, फिर यहाँ ऑफ़लाइन → डाउनलोड की गई फ़ाइलों से इंस्टॉल करें चुनें।", + "engines.state.copying": "कॉपी हो रहा है {0}%", "about.title": "परिचय", "about.updates": "अपडेट", "common.search": "खोजें", diff --git a/src/Filee.App/Assets/i18n/id.json b/src/Filee.App/Assets/i18n/id.json index da7761561..052dfc00e 100644 --- a/src/Filee.App/Assets/i18n/id.json +++ b/src/Filee.App/Assets/i18n/id.json @@ -130,6 +130,8 @@ "error.rhwp_timeout_calibre": "rhwp tidak dapat menyelesaikan dokumen panjang ini tepat waktu. Untuk e-book, pindahkan Calibre ke atas pembuat HWPX di Pengaturan → Engine, dan Calibre akan membuat PDF jauh lebih cepat", "error.engine_stalled": "Engine berhenti merespons: tidak menunjukkan progres dalam waktu lama, sehingga dihentikan", "error.engine_busy": "Filee lain (aplikasi, baris perintah, atau salinan kedua) sedang memasang atau menghapus engine ini. Coba lagi setelah selesai.", + "error.engine_files_missing": "Tidak semua file engine dipilih, atau sebagian untuk versi Filee lain. Engine ini memerlukan file berikut", + "error.engine_file_mismatch": "File ini bukan yang diunduh Filee untuk engine ini: file rusak atau versinya berbeda", "error.needs_shaping": "Skrip ini memerlukan LibreOffice untuk mengonversi dengan benar. Pasang di Pengaturan → Engine", "error.runtime_missing": "File runtime Microsoft Visual C++ yang dibutuhkan engine ini hilang atau kedaluwarsa. Perbarui atau pasang ulang Filee, atau pasang Microsoft Visual C++ Redistributable (x64)", "error.conversion_failed": "Engine melaporkan kesalahan", @@ -1274,6 +1276,17 @@ "engines.state.unpacking": "Memasang…", "engines.state.installed": "Terpasang", "engines.state.failed": "Gagal: {0}", + "engines.offline": "Offline", + "engines.offline_hint": "Tidak ada internet di sini? Pasang dari file yang diunduh di komputer lain, atau simpan file di sana untuk komputer ini.", + "engines.install_from_files": "Pasang dari file yang diunduh…", + "engines.install_from_files_title": "Pilih file {0} yang sudah diunduh", + "engines.save_files": "Simpan file untuk komputer lain…", + "engines.save_files_title": "Pilih tempat menyimpan file {0}", + "engines.save_files_done": "File {0} ada di {1}.\nSalin ke komputer lain, lalu pilih Offline → Pasang dari file yang diunduh di sana. Komputer itu perlu versi Filee yang sama.", + "engines.save_files_failed": "Tidak dapat menyimpan file: {0}", + "engines.copy_links": "Salin tautan unduhan", + "engines.links_copied": "Tautan unduhan sudah ada di papan klip. Unduh file di komputer yang terhubung ke internet, lalu pilih Offline → Pasang dari file yang diunduh di sini.", + "engines.state.copying": "Menyalin {0}%", "about.title": "Tentang", "about.updates": "Pembaruan", "common.search": "Cari", diff --git a/src/Filee.App/Assets/i18n/it.json b/src/Filee.App/Assets/i18n/it.json index 617a58f7d..df17401a4 100644 --- a/src/Filee.App/Assets/i18n/it.json +++ b/src/Filee.App/Assets/i18n/it.json @@ -129,6 +129,8 @@ "error.rhwp_timeout_calibre": "rhwp non è riuscito a completare in tempo questo documento lungo. Per un e-book, sposta Calibre sopra il writer HWPX in Impostazioni → Motori: Calibre crea il PDF molto più in fretta", "error.engine_stalled": "Il motore ha smesso di rispondere: non ha mostrato progressi per molto tempo, quindi è stato interrotto", "error.engine_busy": "Un altro Filee (l'app, la riga di comando o un'altra copia) sta installando o rimuovendo questo motore. Riprova quando ha finito.", +"error.engine_files_missing": "Non sono stati scelti tutti i file del motore, oppure alcuni sono per un'altra versione di Filee. Servono questi file", +"error.engine_file_mismatch": "Questo file non è quello che Filee scarica per questo motore: è danneggiato o di un'altra versione", "error.needs_shaping": "Questa scrittura richiede LibreOffice per essere convertita correttamente. Installalo in Impostazioni → Motori", "error.runtime_missing": "Manca un file di runtime di Microsoft Visual C++ necessario a questo motore, oppure è obsoleto. Aggiorna o reinstalla Filee, oppure installa Microsoft Visual C++ Redistributable (x64)", "error.conversion_failed": "Il motore ha segnalato un errore", @@ -1273,6 +1275,17 @@ "engines.state.unpacking": "Installazione…", "engines.state.installed": "Installato", "engines.state.failed": "Non riuscito: {0}", +"engines.offline": "Offline", +"engines.offline_hint": "Niente internet qui? Installa dai file scaricati su un altro computer, oppure salva lì i file per questo.", +"engines.install_from_files": "Installa da file scaricati…", +"engines.install_from_files_title": "Scegli i file scaricati di {0}", +"engines.save_files": "Salva i file per un altro computer…", +"engines.save_files_title": "Scegli dove salvare i file di {0}", +"engines.save_files_done": "I file di {0} sono in {1}.\nCopiali sull'altro computer e scegli lì Offline → Installa da file scaricati. Serve la stessa versione di Filee.", +"engines.save_files_failed": "Impossibile salvare i file: {0}", +"engines.copy_links": "Copia i link di download", +"engines.links_copied": "I link di download sono negli appunti. Scarica i file su un computer con internet, poi scegli qui Offline → Installa da file scaricati.", +"engines.state.copying": "Copia {0}%", "about.title": "Informazioni", "about.updates": "Aggiornamenti", "common.search": "Cerca", diff --git a/src/Filee.App/Assets/i18n/ja.json b/src/Filee.App/Assets/i18n/ja.json index 027ab60b3..4f5a36060 100644 --- a/src/Filee.App/Assets/i18n/ja.json +++ b/src/Filee.App/Assets/i18n/ja.json @@ -130,6 +130,8 @@ "error.rhwp_timeout_calibre": "文書が長いため、rhwpが制限時間内に処理を終えられませんでした。電子書籍の場合は、「設定」→「変換エンジン」でCalibreを「HWPX writer」より上に移動してください。CalibreならPDFを大幅に速く作成できます", "error.engine_stalled": "変換エンジンが応答しなくなりました。長時間進まなかったため停止しました", "error.engine_busy": "別の Filee(アプリ、コマンドライン、または別のコピー)がこのエンジンをインストールまたは削除しています。終わってから、もう一度お試しください。", + "error.engine_files_missing": "エンジンのファイルがすべて選ばれていないか、一部が別のバージョンの Filee 用です。必要なファイル", + "error.engine_file_mismatch": "このファイルは Filee がこのエンジン用にダウンロードするものではありません。壊れているか、別のバージョンです", "error.needs_shaping": "この文字体系の文書を正しく変換するにはLibreOfficeが必要です。「設定」→「変換エンジン」でインストールしてください", "error.runtime_missing": "このエンジンに必要なMicrosoft Visual C++ランタイムのファイルがないか、古くなっています。Filee を更新または再インストールするか、Microsoft Visual C++ 再頒布可能パッケージ(x64)をインストールしてください", "error.conversion_failed": "変換エンジンからエラーが報告されました", @@ -1274,6 +1276,17 @@ "engines.state.unpacking": "インストール中…", "engines.state.installed": "インストール済み", "engines.state.failed": "失敗:{0}", + "engines.offline": "オフライン", + "engines.offline_hint": "ここではインターネットにつながりませんか?別のコンピューターでダウンロードしたファイルからインストールするか、そのコンピューターでこちら用にファイルを保存できます。", + "engines.install_from_files": "ダウンロードしたファイルからインストール…", + "engines.install_from_files_title": "{0} のダウンロードしたファイルを選んでください", + "engines.save_files": "別のコンピューター用にファイルを保存…", + "engines.save_files_title": "{0} のファイルの保存先を選んでください", + "engines.save_files_done": "{0} のファイルを {1} に保存しました。\n別のコンピューターにコピーし、そちらで「オフライン」→「ダウンロードしたファイルからインストール」を選んでください。同じバージョンの Filee が必要です。", + "engines.save_files_failed": "ファイルを保存できませんでした: {0}", + "engines.copy_links": "ダウンロードリンクをコピー", + "engines.links_copied": "ダウンロードリンクをクリップボードにコピーしました。インターネットにつながるコンピューターでファイルをダウンロードし、ここで「オフライン」→「ダウンロードしたファイルからインストール」を選んでください。", + "engines.state.copying": "コピー中{0}%", "about.title": "Fileeについて", "about.updates": "更新", "common.search": "検索", diff --git a/src/Filee.App/Assets/i18n/ko.json b/src/Filee.App/Assets/i18n/ko.json index b72e1c85a..cd75dc253 100644 --- a/src/Filee.App/Assets/i18n/ko.json +++ b/src/Filee.App/Assets/i18n/ko.json @@ -136,6 +136,8 @@ "error.rhwp_timeout_calibre": "문서가 길어서 rhwp가 제한 시간 안에 끝내지 못했어요. 전자책이라면 설정 → 변환 엔진에서 Calibre를 HWPX writer보다 위로 옮겨 주세요. Calibre가 PDF를 훨씬 빨리 만들어요", "error.engine_stalled": "엔진이 응답하지 않아요. 오랫동안 진행되지 않아서 중지했어요", "error.engine_busy": "다른 Filee(앱, 명령줄 또는 다른 복사본)가 이 엔진을 설치하거나 지우고 있어요. 끝난 뒤에 다시 해 보세요.", + "error.engine_files_missing": "엔진 파일을 다 고르지 않았거나, 일부가 다른 버전의 Filee용이에요. 필요한 파일", + "error.engine_file_mismatch": "이 파일은 Filee가 이 엔진으로 내려받는 파일이 아니에요. 손상됐거나 다른 버전이에요", "error.needs_shaping": "이 문자는 LibreOffice가 있어야 제대로 변환돼요. 설정 → 변환 엔진에서 설치해 주세요", "error.runtime_missing": "이 엔진에 필요한 Microsoft Visual C++ 런타임 파일이 없거나 오래됐어요. Filee를 업데이트하거나 다시 설치하거나, Microsoft Visual C++ 재배포 가능 패키지(x64)를 설치해 주세요", "error.conversion_failed": "엔진에서 오류가 발생했어요", @@ -1291,6 +1293,17 @@ "engines.state.unpacking": "설치하는 중…", "engines.state.installed": "설치됨", "engines.state.failed": "실패: {0}", + "engines.offline": "오프라인", + "engines.offline_hint": "여기서 인터넷이 안 되나요? 다른 컴퓨터에서 내려받은 파일로 설치하거나, 그 컴퓨터에서 이 컴퓨터용 파일을 저장하세요.", + "engines.install_from_files": "내려받은 파일로 설치…", + "engines.install_from_files_title": "{0}의 내려받은 파일을 고르세요", + "engines.save_files": "다른 컴퓨터용으로 파일 저장…", + "engines.save_files_title": "{0}의 파일을 저장할 곳을 고르세요", + "engines.save_files_done": "{0}의 파일을 {1}에 저장했어요.\n다른 컴퓨터로 복사한 뒤 그곳에서 오프라인 → 내려받은 파일로 설치를 고르세요. 같은 버전의 Filee가 필요해요.", + "engines.save_files_failed": "파일을 저장하지 못했어요: {0}", + "engines.copy_links": "내려받기 링크 복사", + "engines.links_copied": "내려받기 링크를 클립보드에 복사했어요. 인터넷이 되는 컴퓨터에서 파일을 내려받은 뒤, 여기서 오프라인 → 내려받은 파일로 설치를 고르세요.", + "engines.state.copying": "복사하는 중 {0}%", "about.title": "정보", "about.updates": "업데이트", diff --git a/src/Filee.App/Assets/i18n/ne.json b/src/Filee.App/Assets/i18n/ne.json index a7e50bee0..885d5d92c 100644 --- a/src/Filee.App/Assets/i18n/ne.json +++ b/src/Filee.App/Assets/i18n/ne.json @@ -130,6 +130,8 @@ "error.rhwp_timeout_calibre": "rhwp ले यस लामो कागजातलाई समयमै पूरा गर्न सकेन। इ-पुस्तकका लागि, सेटिङहरू → इन्जिनहरूमा गएर Calibre लाई HWPX writer भन्दा माथि सार्नुहोस्, र Calibre ले PDF धेरै छिटो बनाउनेछ", "error.engine_stalled": "इन्जिनले प्रतिक्रिया दिन बन्द गर्‍यो: लामो समयसम्म कुनै प्रगति नभएकाले यसलाई रोकियो", "error.engine_busy": "अर्को Filee (एप, कमान्ड लाइन वा अर्को प्रति) ले यो इन्जिन स्थापना गर्दै वा हटाउँदै छ। त्यो सकिएपछि फेरि प्रयास गर्नुहोस्।", + "error.engine_files_missing": "इन्जिनका सबै फाइलहरू छानिएनन्, वा केही Filee को अर्को संस्करणका हुन्। यी फाइलहरू चाहिन्छ", + "error.engine_file_mismatch": "यो फाइल Filee ले यो इन्जिनका लागि डाउनलोड गर्ने फाइल होइन: यो बिग्रिएको छ वा अर्को संस्करण हो", "error.needs_shaping": "यस लिपिलाई सही रूपमा रूपान्तरण गर्न LibreOffice आवश्यक पर्दछ। यसलाई सेटिङहरू → इन्जिनहरूमा स्थापना गर्नुहोस्", "error.runtime_missing": "यो इन्जिनलाई आवश्यक पर्ने Microsoft Visual C++ रनटाइम फाइल फेला परेन वा पुरानो भयो। Filee लाई अपडेट वा पुन: स्थापना गर्नुहोस्, वा Microsoft Visual C++ Redistributable (x64) स्थापना गर्नुहोस्", "error.conversion_failed": "इन्जिनले त्रुटि रिपोर्ट गर्‍यो", @@ -1274,6 +1276,17 @@ "engines.state.unpacking": "स्थापना हुँदैछ…", "engines.state.installed": "स्थापना गरियो", "engines.state.failed": "असफल भयो: {0}", + "engines.offline": "अफलाइन", + "engines.offline_hint": "यहाँ इन्टरनेट छैन? अर्को कम्प्युटरमा डाउनलोड गरिएका फाइलहरूबाट स्थापना गर्नुहोस्, वा त्यहाँ यो कम्प्युटरका लागि फाइलहरू सुरक्षित गर्नुहोस्।", + "engines.install_from_files": "डाउनलोड गरिएका फाइलहरूबाट स्थापना गर्नुहोस्…", + "engines.install_from_files_title": "{0} का डाउनलोड गरिएका फाइलहरू छान्नुहोस्", + "engines.save_files": "अर्को कम्प्युटरका लागि फाइलहरू सुरक्षित गर्नुहोस्…", + "engines.save_files_title": "{0} का फाइलहरू कहाँ सुरक्षित गर्ने छान्नुहोस्", + "engines.save_files_done": "{0} का फाइलहरू {1} मा छन्।\nतिनलाई अर्को कम्प्युटरमा प्रतिलिपि गर्नुहोस् र त्यहाँ अफलाइन → डाउनलोड गरिएका फाइलहरूबाट स्थापना गर्नुहोस् छान्नुहोस्। त्यहाँ Filee को उही संस्करण चाहिन्छ।", + "engines.save_files_failed": "फाइलहरू सुरक्षित गर्न सकिएन: {0}", + "engines.copy_links": "डाउनलोड लिङ्कहरू प्रतिलिपि गर्नुहोस्", + "engines.links_copied": "डाउनलोड लिङ्कहरू क्लिपबोर्डमा प्रतिलिपि भए। इन्टरनेट भएको कम्प्युटरमा फाइलहरू डाउनलोड गर्नुहोस्, त्यसपछि यहाँ अफलाइन → डाउनलोड गरिएका फाइलहरूबाट स्थापना गर्नुहोस् छान्नुहोस्।", + "engines.state.copying": "{0}% प्रतिलिपि हुँदैछ", "about.title": "बारेमा", "about.updates": "अपडेटहरू", "common.search": "खोज्नुहोस्", diff --git a/src/Filee.App/Assets/i18n/pl.json b/src/Filee.App/Assets/i18n/pl.json index 7ac8294ed..7f5b0218a 100644 --- a/src/Filee.App/Assets/i18n/pl.json +++ b/src/Filee.App/Assets/i18n/pl.json @@ -136,6 +136,8 @@ "error.rhwp_timeout_calibre": "rhwp nie zdążył przetworzyć tego długiego dokumentu. Dla e-booka przenieś Calibre nad HWPX writer w Ustawienia → Silniki, a Calibre zrobi PDF znacznie szybciej", "error.engine_stalled": "Silnik przestał odpowiadać: długo nie robił postępów, więc został zatrzymany", "error.engine_busy": "Inny Filee (aplikacja, wiersz poleceń lub druga kopia) instaluje lub usuwa ten silnik. Spróbuj ponownie, gdy skończy.", + "error.engine_files_missing": "Nie wybrano wszystkich plików silnika albo część z nich jest dla innej wersji Filee. Potrzebne są te pliki", + "error.engine_file_mismatch": "To nie jest plik, który Filee pobiera dla tego silnika: jest uszkodzony albo to inna wersja", "error.needs_shaping": "To pismo wymaga LibreOffice do poprawnej konwersji. Zainstaluj go w Ustawienia → Silniki", "error.runtime_missing": "Brakuje pliku środowiska Microsoft Visual C++ potrzebnego temu silnikowi albo jest on nieaktualny. Zaktualizuj lub zainstaluj ponownie Filee albo zainstaluj Microsoft Visual C++ Redistributable (x64)", "error.conversion_failed": "Silnik zgłosił błąd", @@ -1291,6 +1293,17 @@ "engines.state.unpacking": "Instalowanie…", "engines.state.installed": "Zainstalowano", "engines.state.failed": "Błąd: {0}", + "engines.offline": "Offline", + "engines.offline_hint": "Brak internetu? Zainstaluj z plików pobranych na innym komputerze albo zapisz tam pliki dla tego komputera.", + "engines.install_from_files": "Zainstaluj z pobranych plików…", + "engines.install_from_files_title": "Wybierz pobrane pliki: {0}", + "engines.save_files": "Zapisz pliki dla innego komputera…", + "engines.save_files_title": "Wybierz, gdzie zapisać pliki: {0}", + "engines.save_files_done": "Pliki: {0} są w {1}.\nSkopiuj je na drugi komputer i wybierz tam Offline → Zainstaluj z pobranych plików. Potrzebna jest ta sama wersja Filee.", + "engines.save_files_failed": "Nie udało się zapisać plików: {0}", + "engines.copy_links": "Kopiuj linki do pobrania", + "engines.links_copied": "Linki do pobrania są w schowku. Pobierz pliki na komputerze z internetem, a potem wybierz tutaj Offline → Zainstaluj z pobranych plików.", + "engines.state.copying": "Kopiowanie {0}%", "about.title": "O programie", "about.updates": "Aktualizacje", diff --git a/src/Filee.App/Assets/i18n/pt-BR.json b/src/Filee.App/Assets/i18n/pt-BR.json index 3a951e123..88c0c45d1 100644 --- a/src/Filee.App/Assets/i18n/pt-BR.json +++ b/src/Filee.App/Assets/i18n/pt-BR.json @@ -136,6 +136,8 @@ "error.rhwp_timeout_calibre": "O rhwp não conseguiu terminar este documento longo a tempo. Para um e-book, coloque o Calibre acima do gravador de HWPX em Configurações → Motores. O Calibre gera o PDF bem mais rápido", "error.engine_stalled": "O motor parou de responder: ficou muito tempo sem progresso e foi interrompido", "error.engine_busy": "Outro Filee (o app, a linha de comando ou outra cópia) está instalando ou removendo este motor. Tente de novo quando ele terminar.", + "error.engine_files_missing": "Nem todos os arquivos do motor foram escolhidos, ou alguns são de outra versão do Filee. Ele precisa destes arquivos", + "error.engine_file_mismatch": "Este arquivo não é o que o Filee baixa para este motor: está danificado ou é outra versão", "error.needs_shaping": "Este alfabeto precisa do LibreOffice para converter corretamente. Instale-o em Configurações → Motores", "error.runtime_missing": "Falta um arquivo do tempo de execução do Microsoft Visual C++ que este motor precisa, ou ele está desatualizado. Atualize ou reinstale o Filee, ou instale o Microsoft Visual C++ Redistributable (x64)", "error.conversion_failed": "O motor informou um erro", @@ -1291,6 +1293,17 @@ "engines.state.unpacking": "Instalando…", "engines.state.installed": "Instalado", "engines.state.failed": "Falhou: {0}", + "engines.offline": "Offline", + "engines.offline_hint": "Sem internet aqui? Instale a partir de arquivos baixados em outro computador, ou salve lá os arquivos para este.", + "engines.install_from_files": "Instalar de arquivos baixados…", + "engines.install_from_files_title": "Escolha os arquivos baixados de {0}", + "engines.save_files": "Salvar os arquivos para outro computador…", + "engines.save_files_title": "Escolha onde salvar os arquivos de {0}", + "engines.save_files_done": "Os arquivos de {0} estão em {1}.\nCopie-os para o outro computador e escolha lá Offline → Instalar de arquivos baixados. Ele precisa da mesma versão do Filee.", + "engines.save_files_failed": "Não foi possível salvar os arquivos: {0}", + "engines.copy_links": "Copiar links de download", + "engines.links_copied": "Os links de download estão na área de transferência. Baixe os arquivos em um computador com internet e depois escolha aqui Offline → Instalar de arquivos baixados.", + "engines.state.copying": "Copiando {0}%", "about.title": "Sobre", "about.updates": "Atualizações", diff --git a/src/Filee.App/Assets/i18n/pt-PT.json b/src/Filee.App/Assets/i18n/pt-PT.json index 03bd29e2d..050d8771d 100644 --- a/src/Filee.App/Assets/i18n/pt-PT.json +++ b/src/Filee.App/Assets/i18n/pt-PT.json @@ -136,6 +136,8 @@ "error.rhwp_timeout_calibre": "O rhwp não conseguiu concluir este documento longo a tempo. Para um livro digital, coloca o Calibre acima do gerador HWPX em Definições → Motores. O Calibre cria o PDF muito mais depressa", "error.engine_stalled": "O motor deixou de responder: esteve muito tempo sem progresso e foi parado", "error.engine_busy": "Outro Filee (a aplicação, a linha de comandos ou outra cópia) está a instalar ou a remover este motor. Tenta novamente quando terminar.", + "error.engine_files_missing": "Nem todos os ficheiros do motor foram escolhidos, ou alguns são de outra versão do Filee. Ele precisa destes ficheiros", + "error.engine_file_mismatch": "Este ficheiro não é o que o Filee descarrega para este motor: está danificado ou é outra versão", "error.needs_shaping": "Este sistema de escrita precisa do LibreOffice para ser convertido corretamente. Instala-o em Definições → Motores", "error.runtime_missing": "Um componente de execução do Microsoft Visual C++ necessário a este motor está em falta ou desatualizado. Atualiza ou reinstala o Filee, ou instala o Microsoft Visual C++ Redistributable (x64)", "error.conversion_failed": "O motor comunicou um erro", @@ -1291,6 +1293,17 @@ "engines.state.unpacking": "A instalar…", "engines.state.installed": "Instalado", "engines.state.failed": "Falhou: {0}", + "engines.offline": "Offline", + "engines.offline_hint": "Sem internet aqui? Instala a partir de ficheiros descarregados noutro computador, ou guarda lá os ficheiros para este.", + "engines.install_from_files": "Instalar a partir de ficheiros descarregados…", + "engines.install_from_files_title": "Escolhe os ficheiros descarregados de {0}", + "engines.save_files": "Guardar os ficheiros para outro computador…", + "engines.save_files_title": "Escolhe onde guardar os ficheiros de {0}", + "engines.save_files_done": "Os ficheiros de {0} estão em {1}.\nCopia-os para o outro computador e escolhe lá Offline → Instalar a partir de ficheiros descarregados. Ele precisa da mesma versão do Filee.", + "engines.save_files_failed": "Não foi possível guardar os ficheiros: {0}", + "engines.copy_links": "Copiar ligações de transferência", + "engines.links_copied": "As ligações de transferência estão na área de transferência. Descarrega os ficheiros num computador com internet e depois escolhe aqui Offline → Instalar a partir de ficheiros descarregados.", + "engines.state.copying": "A copiar {0}%", "about.title": "Acerca de", "about.updates": "Atualizações", diff --git a/src/Filee.App/Assets/i18n/ru.json b/src/Filee.App/Assets/i18n/ru.json index ef28d8bf6..ebf6d5d12 100644 --- a/src/Filee.App/Assets/i18n/ru.json +++ b/src/Filee.App/Assets/i18n/ru.json @@ -136,6 +136,8 @@ "error.rhwp_timeout_calibre": "rhwp не успел обработать этот длинный документ. Для электронной книги поставьте Calibre выше HWPX writer в разделе «Настройки → Движки» — так Calibre сделает PDF намного быстрее", "error.engine_stalled": "Движок перестал отвечать: он долго не продвигался и был остановлен", "error.engine_busy": "Другой Filee (приложение, командная строка или вторая копия) сейчас устанавливает или удаляет этот движок. Попробуйте снова, когда он закончит.", + "error.engine_files_missing": "Выбраны не все файлы движка, или часть из них — для другой версии Filee. Нужны эти файлы", + "error.engine_file_mismatch": "Это не тот файл, который Filee скачивает для этого движка: он повреждён или другой версии", "error.needs_shaping": "Чтобы правильно сконвертировать текст в этой системе письма, нужен LibreOffice. Установите его в разделе «Настройки → Движки»", "error.runtime_missing": "Не хватает файла среды выполнения Microsoft Visual C++, нужного этому движку, или он устарел. Обновите или переустановите Filee либо установите Microsoft Visual C++ Redistributable (x64)", "error.conversion_failed": "Движок сообщил об ошибке", @@ -1291,6 +1293,17 @@ "engines.state.unpacking": "Устанавливается…", "engines.state.installed": "Установлен", "engines.state.failed": "Ошибка: {0}", + "engines.offline": "Без интернета", + "engines.offline_hint": "Здесь нет интернета? Установите из файлов, скачанных на другом компьютере, или сохраните там файлы для этого.", + "engines.install_from_files": "Установить из скачанных файлов…", + "engines.install_from_files_title": "Выберите скачанные файлы {0}", + "engines.save_files": "Сохранить файлы для другого компьютера…", + "engines.save_files_title": "Выберите, куда сохранить файлы {0}", + "engines.save_files_done": "Файлы {0} сохранены в {1}.\nСкопируйте их на другой компьютер и выберите там «Без интернета» → «Установить из скачанных файлов». Там нужна та же версия Filee.", + "engines.save_files_failed": "Не удалось сохранить файлы: {0}", + "engines.copy_links": "Копировать ссылки для скачивания", + "engines.links_copied": "Ссылки для скачивания скопированы в буфер обмена. Скачайте файлы на компьютере с интернетом, а затем выберите здесь «Без интернета» → «Установить из скачанных файлов».", + "engines.state.copying": "Копируется {0}%", "about.title": "О программе", "about.updates": "Обновления", diff --git a/src/Filee.App/Assets/i18n/th.json b/src/Filee.App/Assets/i18n/th.json index a3949be28..8bc77349b 100644 --- a/src/Filee.App/Assets/i18n/th.json +++ b/src/Filee.App/Assets/i18n/th.json @@ -130,6 +130,8 @@ "error.rhwp_timeout_calibre": "rhwp ไม่สามารถประมวลผลเอกสารขนาดยาวนี้ได้ทันเวลา สำหรับอีบุ๊ก ให้ย้าย Calibre ไปไว้เหนือตัวเขียน HWPX ใน การตั้งค่า → เครื่องมือแปลงไฟล์ Calibre จะสร้าง PDF ได้เร็วกว่ามาก", "error.engine_stalled": "เครื่องมือแปลงไฟล์หยุดตอบสนอง: ไม่มีความคืบหน้าเป็นเวลานาน จึงถูกหยุดการทำงาน", "error.engine_busy": "Filee อีกตัว (แอป บรรทัดคำสั่ง หรือสำเนาอีกชุด) กำลังติดตั้งหรือลบเครื่องมือนี้อยู่ โปรดลองอีกครั้งเมื่อเสร็จแล้ว", + "error.engine_files_missing": "ยังเลือกไฟล์ของเครื่องมือไม่ครบ หรือบางไฟล์เป็นของ Filee รุ่นอื่น ต้องใช้ไฟล์เหล่านี้", + "error.engine_file_mismatch": "ไฟล์นี้ไม่ใช่ไฟล์ที่ Filee ดาวน์โหลดสำหรับเครื่องมือนี้ ไฟล์เสียหายหรือเป็นรุ่นอื่น", "error.needs_shaping": "ภาษานี้ต้องใช้ LibreOffice เพื่อแปลงให้ถูกต้อง ติดตั้งได้ในการตั้งค่า → เครื่องมือแปลงไฟล์", "error.runtime_missing": "ไฟล์รันไทม์ Microsoft Visual C++ ที่เครื่องมือนี้ต้องใช้ขาดหายไปหรือล้าสมัย โปรดอัปเดตหรือติดตั้ง Filee ใหม่ หรือติดตั้ง Microsoft Visual C++ Redistributable (x64)", "error.conversion_failed": "เครื่องมือแปลงไฟล์รายงานข้อผิดพลาด", @@ -1274,6 +1276,17 @@ "engines.state.unpacking": "กำลังติดตั้ง…", "engines.state.installed": "ติดตั้งแล้ว", "engines.state.failed": "ล้มเหลว: {0}", + "engines.offline": "ออฟไลน์", + "engines.offline_hint": "ที่นี่ไม่มีอินเทอร์เน็ตใช่ไหม ติดตั้งจากไฟล์ที่ดาวน์โหลดบนคอมพิวเตอร์เครื่องอื่น หรือบันทึกไฟล์ที่เครื่องนั้นไว้ให้เครื่องนี้", + "engines.install_from_files": "ติดตั้งจากไฟล์ที่ดาวน์โหลดไว้…", + "engines.install_from_files_title": "เลือกไฟล์ที่ดาวน์โหลดไว้ของ {0}", + "engines.save_files": "บันทึกไฟล์ไว้ให้คอมพิวเตอร์เครื่องอื่น…", + "engines.save_files_title": "เลือกที่บันทึกไฟล์ของ {0}", + "engines.save_files_done": "ไฟล์ของ {0} อยู่ใน {1}\nคัดลอกไปยังคอมพิวเตอร์อีกเครื่อง แล้วเลือก ออฟไลน์ → ติดตั้งจากไฟล์ที่ดาวน์โหลดไว้ ที่เครื่องนั้น เครื่องนั้นต้องใช้ Filee รุ่นเดียวกัน", + "engines.save_files_failed": "บันทึกไฟล์ไม่ได้: {0}", + "engines.copy_links": "คัดลอกลิงก์ดาวน์โหลด", + "engines.links_copied": "คัดลอกลิงก์ดาวน์โหลดไปยังคลิปบอร์ดแล้ว ดาวน์โหลดไฟล์บนคอมพิวเตอร์ที่มีอินเทอร์เน็ต แล้วเลือก ออฟไลน์ → ติดตั้งจากไฟล์ที่ดาวน์โหลดไว้ ที่นี่", + "engines.state.copying": "กำลังคัดลอก {0}%", "about.title": "เกี่ยวกับ", "about.updates": "การอัปเดต", "common.search": "ค้นหา", diff --git a/src/Filee.App/Assets/i18n/tr.json b/src/Filee.App/Assets/i18n/tr.json index 8673da070..2605321c2 100644 --- a/src/Filee.App/Assets/i18n/tr.json +++ b/src/Filee.App/Assets/i18n/tr.json @@ -130,6 +130,8 @@ "error.rhwp_timeout_calibre": "rhwp bu uzun belgeyi zamanında tamamlayamadı. E-kitaplar için Ayarlar → Dönüştürme motorları bölümünde Calibre'yi HWPX yazıcısının üstüne taşıyın; Calibre PDF'yi çok daha hızlı oluşturur", "error.engine_stalled": "Motor yanıt vermeyi bıraktı: uzun süre ilerleme göstermediği için durduruldu", "error.engine_busy": "Başka bir Filee (uygulama, komut satırı ya da ikinci bir kopya) bu motoru yüklüyor veya kaldırıyor. Bitince yeniden deneyin.", + "error.engine_files_missing": "Motorun tüm dosyaları seçilmedi ya da bazıları Filee'nin başka bir sürümüne ait. Gereken dosyalar", + "error.engine_file_mismatch": "Bu dosya, Filee'nin bu motor için indirdiği dosya değil: bozuk ya da farklı bir sürüm", "error.needs_shaping": "Bu yazı sisteminin doğru dönüştürülmesi için LibreOffice gerekli. Ayarlar → Dönüştürme motorları bölümünden kurun", "error.runtime_missing": "Bu motorun ihtiyaç duyduğu bir Microsoft Visual C++ çalışma zamanı dosyası eksik veya eski. Filee'yi güncelleyin ya da yeniden kurun veya Microsoft Visual C++ Redistributable (x64) yükleyin", "error.conversion_failed": "Motor bir hata bildirdi", @@ -1274,6 +1276,17 @@ "engines.state.unpacking": "Kuruluyor…", "engines.state.installed": "Kuruldu", "engines.state.failed": "Başarısız: {0}", + "engines.offline": "Çevrimdışı", + "engines.offline_hint": "Burada internet yok mu? Başka bir bilgisayarda indirilen dosyalardan yükleyin ya da orada bu bilgisayar için dosyaları kaydedin.", + "engines.install_from_files": "İndirilen dosyalardan yükle…", + "engines.install_from_files_title": "{0} için indirilen dosyaları seçin", + "engines.save_files": "Dosyaları başka bir bilgisayar için kaydet…", + "engines.save_files_title": "{0} dosyalarının kaydedileceği yeri seçin", + "engines.save_files_done": "{0} dosyaları {1} içinde.\nOnları diğer bilgisayara kopyalayın ve orada Çevrimdışı → İndirilen dosyalardan yükle'yi seçin. Aynı Filee sürümü gerekir.", + "engines.save_files_failed": "Dosyalar kaydedilemedi: {0}", + "engines.copy_links": "İndirme bağlantılarını kopyala", + "engines.links_copied": "İndirme bağlantıları panoya kopyalandı. Dosyaları internete bağlı bir bilgisayarda indirin, ardından burada Çevrimdışı → İndirilen dosyalardan yükle'yi seçin.", + "engines.state.copying": "Kopyalanıyor %{0}", "about.title": "Hakkında", "about.updates": "Güncellemeler", "common.search": "Ara", diff --git a/src/Filee.App/Assets/i18n/vi.json b/src/Filee.App/Assets/i18n/vi.json index 329595271..3a7d97318 100644 --- a/src/Filee.App/Assets/i18n/vi.json +++ b/src/Filee.App/Assets/i18n/vi.json @@ -136,6 +136,8 @@ "error.rhwp_timeout_calibre": "rhwp không kịp xử lý xong tài liệu dài này. Với sách điện tử, hãy chuyển Calibre lên trên trình ghi HWPX trong Cài đặt → Bộ xử lý, Calibre sẽ tạo PDF nhanh hơn nhiều", "error.engine_stalled": "Bộ xử lý đã ngừng phản hồi: rất lâu không có tiến triển nên đã bị dừng", "error.engine_busy": "Một Filee khác (ứng dụng, dòng lệnh hoặc một bản thứ hai) đang cài đặt hoặc gỡ bỏ bộ xử lý này. Hãy thử lại khi việc đó đã xong.", + "error.engine_files_missing": "Chưa chọn đủ các tệp của bộ xử lý, hoặc có tệp thuộc phiên bản Filee khác. Cần các tệp này", + "error.engine_file_mismatch": "Tệp này không phải tệp Filee tải xuống cho bộ xử lý này: tệp bị hỏng hoặc là phiên bản khác", "error.needs_shaping": "Hệ chữ viết này cần LibreOffice để chuyển đổi đúng. Hãy cài LibreOffice trong Cài đặt → Bộ xử lý", "error.runtime_missing": "Một tệp thời gian chạy Microsoft Visual C++ mà bộ xử lý này cần bị thiếu hoặc đã cũ. Hãy cập nhật hoặc cài lại Filee, hoặc cài Microsoft Visual C++ Redistributable (x64)", "error.conversion_failed": "Bộ xử lý báo lỗi", @@ -1291,6 +1293,17 @@ "engines.state.unpacking": "Đang cài đặt…", "engines.state.installed": "Đã cài đặt", "engines.state.failed": "Thất bại: {0}", + "engines.offline": "Ngoại tuyến", + "engines.offline_hint": "Ở đây không có internet? Hãy cài đặt từ các tệp đã tải xuống trên máy tính khác, hoặc lưu các tệp ở đó cho máy này.", + "engines.install_from_files": "Cài đặt từ tệp đã tải xuống…", + "engines.install_from_files_title": "Chọn các tệp đã tải xuống của {0}", + "engines.save_files": "Lưu tệp cho máy tính khác…", + "engines.save_files_title": "Chọn nơi lưu các tệp của {0}", + "engines.save_files_done": "Các tệp của {0} nằm trong {1}.\nHãy sao chép chúng sang máy tính kia và chọn Ngoại tuyến → Cài đặt từ tệp đã tải xuống ở đó. Máy đó cần cùng phiên bản Filee.", + "engines.save_files_failed": "Không lưu được các tệp: {0}", + "engines.copy_links": "Sao chép liên kết tải xuống", + "engines.links_copied": "Các liên kết tải xuống đã được sao chép vào bộ nhớ tạm. Hãy tải các tệp trên một máy tính có internet, rồi chọn Ngoại tuyến → Cài đặt từ tệp đã tải xuống tại đây.", + "engines.state.copying": "Đang sao chép {0}%", "about.title": "Giới thiệu", "about.updates": "Cập nhật", diff --git a/src/Filee.App/Assets/i18n/zh-CN.json b/src/Filee.App/Assets/i18n/zh-CN.json index 98833aa88..ddad1450d 100644 --- a/src/Filee.App/Assets/i18n/zh-CN.json +++ b/src/Filee.App/Assets/i18n/zh-CN.json @@ -136,6 +136,8 @@ "error.rhwp_timeout_calibre": "文档太长,rhwp 未能在时限内完成。如果是电子书,请在“设置 → 转换引擎”中把 Calibre 移到 HWPX writer 之上,Calibre 生成 PDF 要快得多", "error.engine_stalled": "转换引擎停止响应:长时间没有进展,已将其停止", "error.engine_busy": "另一个 Filee(应用、命令行或另一个副本)正在安装或删除这个引擎。请在它完成后重试。", + "error.engine_files_missing": "没有选齐引擎的文件,或其中有些属于其他版本的 Filee。需要这些文件", + "error.engine_file_mismatch": "这个文件不是 Filee 为此引擎下载的文件:它已损坏,或是其他版本", "error.needs_shaping": "这种文字需要 LibreOffice 才能正确转换,请在“设置 → 转换引擎”中安装", "error.runtime_missing": "此引擎所需的 Microsoft Visual C++ 运行库文件缺失或版本过旧。请更新或重新安装 Filee,或安装 Microsoft Visual C++ 可再发行程序包 (x64)", "error.conversion_failed": "转换引擎出错", @@ -1291,6 +1293,17 @@ "engines.state.unpacking": "安装中…", "engines.state.installed": "已安装", "engines.state.failed": "失败:{0}", + "engines.offline": "离线", + "engines.offline_hint": "这里无法联网?可以用在另一台电脑上下载的文件安装,或在那台电脑上为这台电脑保存文件。", + "engines.install_from_files": "从已下载的文件安装…", + "engines.install_from_files_title": "选择 {0} 的已下载文件", + "engines.save_files": "为另一台电脑保存文件…", + "engines.save_files_title": "选择保存 {0} 文件的位置", + "engines.save_files_done": "{0} 的文件已保存在 {1}。\n把它们复制到另一台电脑,在那里选择 离线 → 从已下载的文件安装。那台电脑需要相同版本的 Filee。", + "engines.save_files_failed": "无法保存文件:{0}", + "engines.copy_links": "复制下载链接", + "engines.links_copied": "下载链接已复制到剪贴板。请在能联网的电脑上下载这些文件,然后在这里选择 离线 → 从已下载的文件安装。", + "engines.state.copying": "复制中 {0}%", "about.title": "关于", "about.updates": "更新", diff --git a/src/Filee.App/Assets/i18n/zh-TW.json b/src/Filee.App/Assets/i18n/zh-TW.json index 229c88c39..4121eef7e 100644 --- a/src/Filee.App/Assets/i18n/zh-TW.json +++ b/src/Filee.App/Assets/i18n/zh-TW.json @@ -136,6 +136,8 @@ "error.rhwp_timeout_calibre": "文件太長,rhwp 未能在時限內完成。如果是電子書,請在「設定 → 轉換引擎」中把 Calibre 移到 HWPX writer 之上,Calibre 產生 PDF 要快得多", "error.engine_stalled": "轉換引擎停止回應:長時間沒有進展,已將其停止", "error.engine_busy": "另一個 Filee(應用程式、命令列或另一個副本)正在安裝或移除這個引擎。請在它完成後重試。", + "error.engine_files_missing": "沒有選齊引擎的檔案,或其中有些屬於其他版本的 Filee。需要這些檔案", + "error.engine_file_mismatch": "這個檔案不是 Filee 為此引擎下載的檔案:它已損毀,或是其他版本", "error.needs_shaping": "這種文字需要 LibreOffice 才能正確轉換,請在「設定 → 轉換引擎」中安裝", "error.runtime_missing": "此引擎所需的 Microsoft Visual C++ 執行階段程式庫檔案缺失或版本過舊。請更新或重新安裝 Filee,或安裝 Microsoft Visual C++ 可轉散發套件 (x64)", "error.conversion_failed": "轉換引擎出錯", @@ -1291,6 +1293,17 @@ "engines.state.unpacking": "安裝中…", "engines.state.installed": "已安裝", "engines.state.failed": "失敗:{0}", + "engines.offline": "離線", + "engines.offline_hint": "這裡無法連網?可以用在另一台電腦上下載的檔案安裝,或在那台電腦上為這台電腦儲存檔案。", + "engines.install_from_files": "從已下載的檔案安裝…", + "engines.install_from_files_title": "選擇 {0} 的已下載檔案", + "engines.save_files": "為另一台電腦儲存檔案…", + "engines.save_files_title": "選擇儲存 {0} 檔案的位置", + "engines.save_files_done": "{0} 的檔案已儲存在 {1}。\n把它們複製到另一台電腦,在那裡選擇 離線 → 從已下載的檔案安裝。那台電腦需要相同版本的 Filee。", + "engines.save_files_failed": "無法儲存檔案:{0}", + "engines.copy_links": "複製下載連結", + "engines.links_copied": "下載連結已複製到剪貼簿。請在能連網的電腦上下載這些檔案,然後在這裡選擇 離線 → 從已下載的檔案安裝。", + "engines.state.copying": "複製中 {0}%", "about.title": "關於", "about.updates": "更新", diff --git a/src/Filee.App/Services/EngineDownloadService.cs b/src/Filee.App/Services/EngineDownloadService.cs index 8f7a115b0..7133dc955 100644 --- a/src/Filee.App/Services/EngineDownloadService.cs +++ b/src/Filee.App/Services/EngineDownloadService.cs @@ -18,6 +18,8 @@ public enum EnginePackageStatus NotInstalled, Queued, Downloading, + /// Copying and checking files the user brought (Install from downloaded files, #447). + Copying, Unpacking, Installed, Failed, @@ -66,7 +68,7 @@ public string? InstallGuidance [ObservableProperty] [NotifyPropertyChangedFor(nameof(StatusText), nameof(IsInstalled), nameof(IsBusy), nameof(CanInstall), nameof(CanRemove), - nameof(UsesOwnCopy), nameof(CanUseOwnCopy), nameof(ShowsCopyFolder), nameof(CanUpdate))] + nameof(UsesOwnCopy), nameof(CanUseOwnCopy), nameof(ShowsCopyFolder), nameof(CanUpdate), nameof(HasOfflineMenu), nameof(CanInstallFromFiles))] private EnginePackageStatus _status; /// @@ -74,7 +76,7 @@ public string? InstallGuidance /// update): offers the new one. /// [ObservableProperty] - [NotifyPropertyChangedFor(nameof(StatusText), nameof(CanUpdate))] + [NotifyPropertyChangedFor(nameof(StatusText), nameof(CanUpdate), nameof(CanInstallFromFiles))] private bool _isOutdated; /// The version Filee downloads now, e.g. "8.0" for FFmpeg (the package's main component). @@ -89,7 +91,7 @@ public string? InstallGuidance /// The copy in use was found on the PC (PATH, Program Files), not chosen by the user. [ObservableProperty] - [NotifyPropertyChangedFor(nameof(StatusText), nameof(CanInstall), nameof(UsesOwnCopy), nameof(CanUseOwnCopy))] + [NotifyPropertyChangedFor(nameof(StatusText), nameof(CanInstall), nameof(UsesOwnCopy), nameof(CanUseOwnCopy), nameof(CanInstallFromFiles))] private bool _fromSystem; /// "Update recommended: 7.1 here, Filee is tested with 9.0" for an older copy, else null. @@ -121,15 +123,26 @@ public string? InstallGuidance public bool ShowsCopyFolder => Status == EnginePackageStatus.OwnCopy; public bool CanUseOwnCopy => Status is EnginePackageStatus.NotInstalled or EnginePackageStatus.Failed or EnginePackageStatus.Installed || (Status == EnginePackageStatus.OwnCopy && FromSystem); - public bool IsBusy => Status is EnginePackageStatus.Queued or EnginePackageStatus.Downloading or EnginePackageStatus.Unpacking; + public bool IsBusy => Status is EnginePackageStatus.Queued or EnginePackageStatus.Downloading or EnginePackageStatus.Copying + or EnginePackageStatus.Unpacking; /// Also when a copy on the PC is used: Filee's download is the tested version and wins once installed. public bool CanInstall => EngineDownloads.CanDownload(Package) && (Status is EnginePackageStatus.NotInstalled or EnginePackageStatus.Failed || (Status == EnginePackageStatus.OwnCopy && FromSystem)); + /// + /// The card's "Offline" menu (#447): install from files downloaded elsewhere, save the files for a computer without + /// internet, copy the download links. Only for packages Filee downloads here, and not while one is busy. + /// + public bool HasOfflineMenu => EngineDownloads.CanDownload(Package) && !IsBusy; + + /// The files can be installed where Install or Update would download them. + public bool CanInstallFromFiles => CanInstall || CanUpdate; + public string StatusText => Status switch { EnginePackageStatus.Queued => _loc["engines.state.queued"], EnginePackageStatus.Downloading => _loc.Format("engines.state.downloading", (int)Progress), + EnginePackageStatus.Copying => _loc.Format("engines.state.copying", (int)Progress), EnginePackageStatus.Unpacking => _loc["engines.state.unpacking"], EnginePackageStatus.Installed => IsOutdated ? _loc.Format("engines.state.update_available", Version ?? "") : _loc["engines.state.installed"], EnginePackageStatus.OwnCopy => _loc[FromSystem ? "engines.state.system_copy" : "engines.state.own_copy"], @@ -183,6 +196,12 @@ public sealed class EngineDownloadService /// Downloads and unpacks one package; tests swap it to hold an install open. internal Func, CancellationToken, Task> InstallPackage { get; set; } + /// Installs one package from the user's files (); tests swap it. + internal Func, IProgress, CancellationToken, Task> InstallPackageFromFiles { get; set; } + + /// Saves one package's downloads in a folder (); tests swap it. + internal Func, CancellationToken, Task> SavePackageFiles { get; set; } + public EngineDownloadService(ConverterCatalog catalog, ILocalizer loc, ILogger logger) { _catalog = catalog; @@ -190,6 +209,8 @@ public EngineDownloadService(ConverterCatalog catalog, ILocalizer loc, ILogger new EnginePackageState(p, loc)).ToList(); if (loc is LocalizationService localization) localization.LanguageChanged += (_, _) => Packages.ToList().ForEach(p => p.Relocalize()); @@ -245,12 +266,69 @@ await Dispatcher.UIThread.InvokeAsync(() => /// /// Downloads and installs a package, or the new version of an outdated one; packages queue up and install one - /// after another. + /// after another. With the downloads are taken from those files or folders instead (#447). /// - public async Task InstallAsync(EnginePackageState state) + public async Task InstallAsync(EnginePackageState state, IReadOnlyList? files = null) { if (!state.CanInstall && !state.CanUpdate) return; + try + { + await RunQueuedAsync(state, (progress, token) => files is null + ? InstallPackage(state.Package, progress, token) + : InstallPackageFromFiles(state.Package, files, progress, token)); + state.Status = EnginePackageStatus.Installed; + _catalog.Refresh(); + if (state.Package.ConverterIds.Contains("libreoffice")) + WarmUpInBackground(TimeSpan.Zero); + } + catch (OperationCanceledException) + { + state.Status = StatusOf(state); + } + catch (Exception ex) + { + _logger.LogError(ex, "Installing engine package {Package} failed", state.Package.Id); + state.Error = ErrorText(_loc, ex); + state.Status = EnginePackageStatus.Failed; + } + } + + /// + /// Saves a package's downloads in for a computer without internet (#447), in the same + /// queue as installs, with the card showing the download. What is installed stays as it was. Returns null when the + /// files are saved (Saved), else the reason when it failed (null when it was cancelled). + /// + public async Task<(bool Saved, string? Error)> SaveFilesAsync(EnginePackageState state, string folder) + { + if (state.IsBusy || !EngineDownloads.CanDownload(state.Package)) + return (false, null); + try + { + await RunQueuedAsync(state, (progress, token) => SavePackageFiles(state.Package, folder, progress, token)); + return (true, null); + } + catch (OperationCanceledException) + { + return (false, null); + } + catch (Exception ex) + { + _logger.LogError(ex, "Saving the files of engine package {Package} failed", state.Package.Id); + return (false, ErrorText(_loc, ex)); + } + finally + { + state.Status = StatusOf(state); + } + } + + /// + /// Runs for a package when the packages before it have finished, with its progress on the + /// package's card. Its errors are the caller's. + /// + private async Task RunQueuedAsync(EnginePackageState state, Func, CancellationToken, Task> work) + { using var cancellation = new CancellationTokenSource(); state.Cancellation = cancellation; state.Error = null; @@ -268,7 +346,12 @@ public async Task InstallAsync(EnginePackageState state) { if (!state.IsBusy) return; - state.Status = p.Stage == EngineInstallStage.Downloading ? EnginePackageStatus.Downloading : EnginePackageStatus.Unpacking; + state.Status = p.Stage switch + { + EngineInstallStage.Downloading => EnginePackageStatus.Downloading, + EngineInstallStage.Copying => EnginePackageStatus.Copying, + _ => EnginePackageStatus.Unpacking, + }; state.Progress = p.Fraction * 100; if (p.Stage == EngineInstallStage.Downloading && p.BytesTotal > 0) { @@ -280,26 +363,12 @@ public async Task InstallAsync(EnginePackageState state) state.ProgressDetail = ""; } }); - await Task.Run(() => InstallPackage(state.Package, progress, cancellation.Token), cancellation.Token); + await Task.Run(() => work(progress, cancellation.Token), cancellation.Token); } finally { _oneAtATime.Release(); } - state.Status = EnginePackageStatus.Installed; - _catalog.Refresh(); - if (state.Package.ConverterIds.Contains("libreoffice")) - WarmUpInBackground(TimeSpan.Zero); - } - catch (OperationCanceledException) - { - state.Status = StatusOf(state); - } - catch (Exception ex) - { - _logger.LogError(ex, "Installing engine package {Package} failed", state.Package.Id); - state.Error = ErrorText(_loc, ex); - state.Status = EnginePackageStatus.Failed; } finally { diff --git a/src/Filee.App/ViewModels/Pages/EnginesPageViewModel.cs b/src/Filee.App/ViewModels/Pages/EnginesPageViewModel.cs index fd6baa56c..ad0f0a47d 100644 --- a/src/Filee.App/ViewModels/Pages/EnginesPageViewModel.cs +++ b/src/Filee.App/ViewModels/Pages/EnginesPageViewModel.cs @@ -120,6 +120,15 @@ partial void OnLibreOfficeForSheetsChanged(bool value) [RelayCommand] private void Cancel(EnginePackageState package) => _downloads.Cancel(package); + /// Installs a package from files the user downloaded elsewhere (#447); a failure shows on its card. + public Task InstallFromFilesAsync(EnginePackageState package, IReadOnlyList files) => _downloads.InstallAsync(package, files); + + /// Saves a package's downloads in for a computer without internet (#447). + public Task<(bool Saved, string? Error)> SaveFilesAsync(EnginePackageState package, string folder) => _downloads.SaveFilesAsync(package, folder); + + /// Name, URL and SHA-256 of each of a package's downloads, to fetch them elsewhere (#447). + public static string DownloadLinks(EnginePackageState package) => EngineDownloads.DownloadList(package.Package, EngineDownloads.Components); + /// Removes a package (after the view asked for confirmation). False when its files are in use. /// Removes a package: null when it's gone, else the key of the reason (see ). public string? Remove(EnginePackageState package) => _downloads.Uninstall(package); diff --git a/src/Filee.App/Views/Pages/EnginesPage.axaml b/src/Filee.App/Views/Pages/EnginesPage.axaml index 5b0872fe9..dd12e29f2 100644 --- a/src/Filee.App/Views/Pages/EnginesPage.axaml +++ b/src/Filee.App/Views/Pages/EnginesPage.axaml @@ -66,6 +66,17 @@