Compare commits

...

23 Commits

Author SHA1 Message Date
ema
342f14ebd9 Add KrcDetector for .krc file support
Some checks are pending
MSBuild / build (push) Waiting to run
MSBuild / publish (push) Blocked by required conditions
2025-09-28 03:04:44 +08:00
ema
3fbfd78123 Update changelog and supported formats 2025-09-28 02:00:41 +08:00
ema
0ba37f6425 Add .snupkg support to archive viewer
Some checks failed
MSBuild / build (push) Has been cancelled
MSBuild / publish (push) Has been cancelled
Included the .snupkg extension in the list of supported archive formats to allow viewing of symbol package files.
2025-09-27 03:37:53 +08:00
ema
ad1730cf4a Expand supported text file formats list
Some checks failed
MSBuild / build (push) Has been cancelled
MSBuild / publish (push) Has been cancelled
Added a comprehensive list of supported text and script file extensions to SUPPORTED_FORMATS.md, detailing various programming, configuration, and markup formats recognized by QuickLook.
2025-09-25 01:32:53 +08:00
ema
7e44fdf29d Update README with supported formats link
Replaces the supported file types section with a link to SUPPORTED_FORMATS.md for better documentation organization.
2025-09-25 01:04:16 +08:00
ema
ba7658e5b8 Reformat Translations.config for consistent indentation 2025-09-25 00:22:26 +08:00
ema
bee13755cc Add translations for PDFViewer
Added password prompt translations for 20+ languages to Translations.config in PDFViewer plugin, improving localization for password-protected PDF files.
2025-09-25 00:21:44 +08:00
ema
ac5250b3eb Remove Translations.config for OfficeViewer 2025-09-25 00:18:16 +08:00
ema
4318646867 Add translations for HtmlViewer
Added localized WEBVIEW2_NOT_AVAILABLE messages for ca, he, hi, hu-HU, id-ID, mr, nb-NO, nl-NL, pt-BR, pt-PT, ru-RU, sk, tr-TR, and vi to improve international support in the HTML viewer plugin.
2025-09-25 00:14:03 +08:00
ema
9b72f6a3da Add translations for FontViewer
Added localized SAMPLE_TEXT entries for various languages including Arabic, Catalan, Greek, Spanish, French, Hebrew, Hindi, Hungarian, Indonesian, Italian, Japanese, Marathi, Norwegian, Dutch, Polish, Brazilian Portuguese, European Portuguese, Russian, Slovak, Turkish, Ukrainian, and Vietnamese to improve font preview support.
2025-09-25 00:04:52 +08:00
ema
13dc9c4f61 Reformat Translations.config for consistent indentation 2025-09-25 00:04:30 +08:00
ema
aaf4c4cfb5 Add translations for ELFViewer
Added support for multiple languages in the Translations.config file for ELFViewer, including Arabic, Catalan, Greek, Spanish, French, Hebrew, Hindi, Hungarian, Indonesian, Italian, Marathi, Norwegian, Dutch, Polish, Portuguese, Russian, Slovak, Turkish, Ukrainian, and Vietnamese. This enhances localization for key labels such as Total Size, Format, Format Profile, and Name.
2025-09-24 23:59:38 +08:00
ema
47b664ada4 Add translations for CLSIDViewer
Added localized strings for recycle bin actions and messages in various languages including Arabic, Catalan, Greek, Hebrew, Hindi, Hungarian, Indonesian, Italian, Marathi, Norwegian, Dutch, Polish, Brazilian Portuguese, European Portuguese, Russian, Slovak, Turkish, Ukrainian, and Vietnamese.
2025-09-24 23:58:31 +08:00
ema
fe96f9c3dd Add translations for AppViewer
Added new language sections to Translations.config for Arabic (ar), Hungarian (hu-HU), Slovak (sk), and Indonesian (id-ID), providing localized strings for product and app metadata fields.
2025-09-24 23:57:39 +08:00
ema
1fa31d0983 Add 'Copy' and 'Select All' translations for more languages
Added 'Editor_Copy' and 'Editor_SelectAll' translations for Arabic, Catalan, Norwegian, Dutch, Polish, Portuguese, Russian, Turkish, Vietnamese, Marathi, Hindi, Hebrew, Hungarian, Indonesian, and Slovak to improve localization coverage.
2025-09-24 23:55:18 +08:00
ema
894c1c1a89 Add and update translations for PEViewer
Expanded Translations.config with additional languages and updated some existing translations for 'Total Size', 'File Version', and 'Product Version'. Also corrected the Traditional Chinese translation for 'Total Size'.
2025-09-24 23:51:49 +08:00
ema
701d20fe7a Add translations for 'Show Media Info' menu item 2025-09-24 23:49:54 +08:00
ema
4fa57b70ba Refactor MoreMenuProvider into Plugin partial class 2025-09-24 23:37:29 +08:00
ema
2317fad8e3 Support MediaInfoViewer in more menu 2025-09-24 23:34:07 +08:00
ema
2570429cdc Fix HelixViewer default height being too large
Some checks failed
MSBuild / build (push) Has been cancelled
MSBuild / publish (push) Has been cancelled
2025-09-22 09:59:00 +08:00
Copilot
ad95955666 Add support for Telegram Sticker (.tgs) files (#1762)
Some checks failed
MSBuild / build (push) Has been cancelled
MSBuild / publish (push) Has been cancelled
2025-09-22 04:57:56 +08:00
ema
1711874779 Add 'Copy as Path' translations 2025-09-22 04:37:27 +08:00
ema
120aa6c445 Add supported formats note for audio cover art
Some checks failed
MSBuild / build (push) Has been cancelled
MSBuild / publish (push) Has been cancelled
2025-09-21 01:13:37 +08:00
38 changed files with 1668 additions and 200 deletions

View File

@@ -1,3 +1,7 @@
## 4.2.0
- Add built-in MediaInfoViewer plugin
## 4.1.1
- Add built-in ThumbnailViewer plugin [#1662](https://github.com/QL-Win/QuickLook/issues/1662)

View File

@@ -1,6 +1,138 @@
<?xml version="1.0" encoding="utf-8"?>
<Translations>
<ar>
<PRODUCT_VERSION>إصدار المنتج</PRODUCT_VERSION>
<PRODUCT_NAME>اسم المنتج</PRODUCT_NAME>
<MANUFACTURER>الشركة المصنعة</MANUFACTURER>
<TOTAL_SIZE>الحجم الكلي</TOTAL_SIZE>
<LAST_MODIFIED>آخر تعديل</LAST_MODIFIED>
<PUBLISHER>الناشر</PUBLISHER>
<CAPABILITIES>القدرات</CAPABILITIES>
<ABI>ABI</ABI>
<APP_NAME>التطبيق</APP_NAME>
<APP_VERSION>الإصدار</APP_VERSION>
<APP_VERSION_NAME>اسم الإصدار</APP_VERSION_NAME>
<APP_VERSION_CODE>رمز الإصدار</APP_VERSION_CODE>
<PERMISSIONS>الأذونات</PERMISSIONS>
<PACKAGE_NAME>اسم الحزمة</PACKAGE_NAME>
<APP_MIN_SDK_VERSION>أدنى إصدار SDK</APP_MIN_SDK_VERSION>
<APP_TARGET_SDK_VERSION>إصدار SDK المستهدف</APP_TARGET_SDK_VERSION>
<APP_MIN_OS_VERSION>أدنى إصدار نظام</APP_MIN_OS_VERSION>
<APP_TARGET_OS_VERSION>إصدار النظام المستهدف</APP_TARGET_OS_VERSION>
<DEVICE_FAMILY>عائلة الجهاز</DEVICE_FAMILY>
<BUNDLE_NAME>اسم الحزمة</BUNDLE_NAME>
<DEVICE_TYPES>أنواع الأجهزة</DEVICE_TYPES>
<APP_MIN_API_VERSION>أدنى إصدار API</APP_MIN_API_VERSION>
<APP_TARGET_API_VERSION>إصدار API المستهدف</APP_TARGET_API_VERSION>
<COMPILE_SDK_VERSION>إصدار SDK المترجم</COMPILE_SDK_VERSION>
<ARCHITECTURE>البنية</ARCHITECTURE>
<MAINTAINER>المسؤول</MAINTAINER>
<DESCRIPTION>الوصف</DESCRIPTION>
<ENVIRONMENT>البيئة</ENVIRONMENT>
<TYPE>النوع</TYPE>
<TERMINAL>طرفية</TERMINAL>
<VENDOR>المورد</VENDOR>
</ar>
<hu-HU>
<PRODUCT_VERSION>Termékverzió</PRODUCT_VERSION>
<PRODUCT_NAME>Terméknév</PRODUCT_NAME>
<MANUFACTURER>Gyártó</MANUFACTURER>
<TOTAL_SIZE>Teljes méret</TOTAL_SIZE>
<LAST_MODIFIED>Utoljára módosítva</LAST_MODIFIED>
<PUBLISHER>Kiadó</PUBLISHER>
<CAPABILITIES>Képességek</CAPABILITIES>
<ABI>ABI</ABI>
<APP_NAME>Alkalmazás</APP_NAME>
<APP_VERSION>Verzió</APP_VERSION>
<APP_VERSION_NAME>Verzió neve</APP_VERSION_NAME>
<APP_VERSION_CODE>Verzió kód</APP_VERSION_CODE>
<PERMISSIONS>Engedélyek</PERMISSIONS>
<PACKAGE_NAME>Csomagnév</PACKAGE_NAME>
<APP_MIN_SDK_VERSION>Minimális SDK verzió</APP_MIN_SDK_VERSION>
<APP_TARGET_SDK_VERSION>Cél SDK verzió</APP_TARGET_SDK_VERSION>
<APP_MIN_OS_VERSION>Minimális OS verzió</APP_MIN_OS_VERSION>
<APP_TARGET_OS_VERSION>Cél OS verzió</APP_TARGET_OS_VERSION>
<DEVICE_FAMILY>Eszközcsalád</DEVICE_FAMILY>
<BUNDLE_NAME>Csomagnév</BUNDLE_NAME>
<DEVICE_TYPES>Eszköztípusok</DEVICE_TYPES>
<APP_MIN_API_VERSION>Minimális API verzió</APP_MIN_API_VERSION>
<APP_TARGET_API_VERSION>Cél API verzió</APP_TARGET_API_VERSION>
<COMPILE_SDK_VERSION>Fordított SDK verzió</COMPILE_SDK_VERSION>
<ARCHITECTURE>Architektúra</ARCHITECTURE>
<MAINTAINER>Karbantartó</MAINTAINER>
<DESCRIPTION>Leírás</DESCRIPTION>
<ENVIRONMENT>Környezet</ENVIRONMENT>
<TYPE>Típus</TYPE>
<TERMINAL>Terminál</TERMINAL>
<VENDOR>Szállító</VENDOR>
</hu-HU>
<sk>
<PRODUCT_VERSION>Verzia produktu</PRODUCT_VERSION>
<PRODUCT_NAME>Názov produktu</PRODUCT_NAME>
<MANUFACTURER>Výrobca</MANUFACTURER>
<TOTAL_SIZE>Celková veľkosť</TOTAL_SIZE>
<LAST_MODIFIED>Posledná zmena</LAST_MODIFIED>
<PUBLISHER>Vydavateľ</PUBLISHER>
<CAPABILITIES>Schopnosti</CAPABILITIES>
<ABI>ABI</ABI>
<APP_NAME>Aplikácia</APP_NAME>
<APP_VERSION>Verzia</APP_VERSION>
<APP_VERSION_NAME>Názov verzie</APP_VERSION_NAME>
<APP_VERSION_CODE>Kód verzie</APP_VERSION_CODE>
<PERMISSIONS>Povolenia</PERMISSIONS>
<PACKAGE_NAME>Názov balíka</PACKAGE_NAME>
<APP_MIN_SDK_VERSION>Minimálna verzia SDK</APP_MIN_SDK_VERSION>
<APP_TARGET_SDK_VERSION>Cieľová verzia SDK</APP_TARGET_SDK_VERSION>
<APP_MIN_OS_VERSION>Minimálna verzia OS</APP_MIN_OS_VERSION>
<APP_TARGET_OS_VERSION>Cieľová verzia OS</APP_TARGET_OS_VERSION>
<DEVICE_FAMILY>Rodina zariadení</DEVICE_FAMILY>
<BUNDLE_NAME>Názov balíka</BUNDLE_NAME>
<DEVICE_TYPES>Typy zariadení</DEVICE_TYPES>
<APP_MIN_API_VERSION>Minimálna verzia API</APP_MIN_API_VERSION>
<APP_TARGET_API_VERSION>Cieľová verzia API</APP_TARGET_API_VERSION>
<COMPILE_SDK_VERSION>Verzia kompilovaného SDK</COMPILE_SDK_VERSION>
<ARCHITECTURE>Architektúra</ARCHITECTURE>
<MAINTAINER>Správca</MAINTAINER>
<DESCRIPTION>Popis</DESCRIPTION>
<ENVIRONMENT>Prostredie</ENVIRONMENT>
<TYPE>Typ</TYPE>
<TERMINAL>Terminál</TERMINAL>
<VENDOR>Dodávateľ</VENDOR>
</sk>
<id-ID>
<PRODUCT_VERSION>Versi produk</PRODUCT_VERSION>
<PRODUCT_NAME>Nama produk</PRODUCT_NAME>
<MANUFACTURER>Pabrikan</MANUFACTURER>
<TOTAL_SIZE>Ukuran total</TOTAL_SIZE>
<LAST_MODIFIED>Terakhir diubah</LAST_MODIFIED>
<PUBLISHER>Penerbit</PUBLISHER>
<CAPABILITIES>Kemampuan</CAPABILITIES>
<ABI>ABI</ABI>
<APP_NAME>Aplikasi</APP_NAME>
<APP_VERSION>Versi</APP_VERSION>
<APP_VERSION_NAME>Nama versi</APP_VERSION_NAME>
<APP_VERSION_CODE>Kode versi</APP_VERSION_CODE>
<PERMISSIONS>Izin</PERMISSIONS>
<PACKAGE_NAME>Nama paket</PACKAGE_NAME>
<APP_MIN_SDK_VERSION>Versi SDK minimum</APP_MIN_SDK_VERSION>
<APP_TARGET_SDK_VERSION>Versi SDK target</APP_TARGET_SDK_VERSION>
<APP_MIN_OS_VERSION>Versi OS minimum</APP_MIN_OS_VERSION>
<APP_TARGET_OS_VERSION>Versi OS target</APP_TARGET_OS_VERSION>
<DEVICE_FAMILY>Keluarga perangkat</DEVICE_FAMILY>
<BUNDLE_NAME>Nama bundle</BUNDLE_NAME>
<DEVICE_TYPES>Jenis perangkat</DEVICE_TYPES>
<APP_MIN_API_VERSION>Versi API minimum</APP_MIN_API_VERSION>
<APP_TARGET_API_VERSION>Versi API target</APP_TARGET_API_VERSION>
<COMPILE_SDK_VERSION>Versi SDK kompilasi</COMPILE_SDK_VERSION>
<ARCHITECTURE>Arsitektur</ARCHITECTURE>
<MAINTAINER>Pemelihara</MAINTAINER>
<DESCRIPTION>Deskripsi</DESCRIPTION>
<ENVIRONMENT>Lingkungan</ENVIRONMENT>
<TYPE>Jenis</TYPE>
<TERMINAL>Terminal</TERMINAL>
<VENDOR>Vendor</VENDOR>
</id-ID>
<en>
<PRODUCT_VERSION>Product Version</PRODUCT_VERSION>
<PRODUCT_NAME>Product Name</PRODUCT_NAME>

View File

@@ -33,7 +33,7 @@ public class Plugin : IViewer
".gz",
".jar",
".lz",
".nupkg",
".nupkg", ".snupkg",
".rar",
".tar", ".tgz",
".vsix",

View File

@@ -1,6 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<Translations>
<ar>
<RecycleBinEmptyText>سلة المحذوفات فارغة</RecycleBinEmptyText>
<RecycleBinButton>إفراغ سلة المحذوفات</RecycleBinButton>
<ConfirmDeleteText>هل أنت متأكد أنك تريد حذف هذه العناصر {0} نهائيًا؟</ConfirmDeleteText>
<RecycleBinSizeText>الحجم الكلي {0}، عدد العناصر {1}</RecycleBinSizeText>
</ar>
<ca>
<RecycleBinEmptyText>La paperera està buida</RecycleBinEmptyText>
<RecycleBinButton>Buida la paperera</RecycleBinButton>
<ConfirmDeleteText>Segur que vols eliminar definitivament aquests {0} elements?</ConfirmDeleteText>
<RecycleBinSizeText>Mida total {0}, {1} elements</RecycleBinSizeText>
</ca>
<el>
<RecycleBinEmptyText>Ο κάδος ανακύκλωσης είναι άδειος</RecycleBinEmptyText>
<RecycleBinButton>Άδειασμα κάδου ανακύκλωσης</RecycleBinButton>
<ConfirmDeleteText>Είστε βέβαιοι ότι θέλετε να διαγράψετε οριστικά αυτά τα {0} στοιχεία;</ConfirmDeleteText>
<RecycleBinSizeText>Συνολικό μέγεθος {0}, {1} στοιχεία</RecycleBinSizeText>
</el>
<he>
<RecycleBinEmptyText>סל המחזור ריק</RecycleBinEmptyText>
<RecycleBinButton>רוקן את סל המחזור</RecycleBinButton>
<ConfirmDeleteText>האם אתה בטוח שברצונך למחוק לצמיתות את {0} פריטים אלה?</ConfirmDeleteText>
<RecycleBinSizeText>גודל כולל {0}, {1} פריטים</RecycleBinSizeText>
</he>
<hi>
<RecycleBinEmptyText>रीसायकल बिन खाली है</RecycleBinEmptyText>
<RecycleBinButton>रीसायकल बिन खाली करें</RecycleBinButton>
<ConfirmDeleteText>क्या आप वाकई इन {0} आइटम्स को स्थायी रूप से हटाना चाहते हैं?</ConfirmDeleteText>
<RecycleBinSizeText>कुल आकार {0}, {1} आइटम्स</RecycleBinSizeText>
</hi>
<hu-HU>
<RecycleBinEmptyText>A lomtár üres</RecycleBinEmptyText>
<RecycleBinButton>Lomtár ürítése</RecycleBinButton>
<ConfirmDeleteText>Biztosan törölni szeretné ezt a(z) {0} elemet véglegesen?</ConfirmDeleteText>
<RecycleBinSizeText>Teljes méret {0}, {1} elem</RecycleBinSizeText>
</hu-HU>
<id-ID>
<RecycleBinEmptyText>Tempat Sampah kosong</RecycleBinEmptyText>
<RecycleBinButton>Kosongkan Tempat Sampah</RecycleBinButton>
<ConfirmDeleteText>Apakah Anda yakin ingin menghapus {0} item ini secara permanen?</ConfirmDeleteText>
<RecycleBinSizeText>Ukuran total {0}, {1} item</RecycleBinSizeText>
</id-ID>
<it>
<RecycleBinEmptyText>Il cestino è vuoto</RecycleBinEmptyText>
<RecycleBinButton>Svuota cestino</RecycleBinButton>
<ConfirmDeleteText>Sei sicuro di voler eliminare definitivamente questi {0} elementi?</ConfirmDeleteText>
<RecycleBinSizeText>Dimensione totale {0}, {1} elementi</RecycleBinSizeText>
</it>
<mr>
<RecycleBinEmptyText>पुनःप्राप्ती बिन रिकामी आहे</RecycleBinEmptyText>
<RecycleBinButton>पुनःप्राप्ती बिन रिकामा करा</RecycleBinButton>
<ConfirmDeleteText>आपण खरोखरच ही {0} आयटम्स कायमचे हटवू इच्छिता?</ConfirmDeleteText>
<RecycleBinSizeText>एकूण आकार {0}, {1} आयटम्स</RecycleBinSizeText>
</mr>
<nb-NO>
<RecycleBinEmptyText>Papirkurven er tom</RecycleBinEmptyText>
<RecycleBinButton>Tøm papirkurven</RecycleBinButton>
<ConfirmDeleteText>Er du sikker på at du vil slette disse {0} elementene permanent?</ConfirmDeleteText>
<RecycleBinSizeText>Total størrelse {0}, {1} elementer</RecycleBinSizeText>
</nb-NO>
<nl-NL>
<RecycleBinEmptyText>Prullenbak is leeg</RecycleBinEmptyText>
<RecycleBinButton>Prullenbak legen</RecycleBinButton>
<ConfirmDeleteText>Weet je zeker dat je deze {0} items permanent wilt verwijderen?</ConfirmDeleteText>
<RecycleBinSizeText>Totale grootte {0}, {1} items</RecycleBinSizeText>
</nl-NL>
<pl>
<RecycleBinEmptyText>Kosz jest pusty</RecycleBinEmptyText>
<RecycleBinButton>Opróżnij kosz</RecycleBinButton>
<ConfirmDeleteText>Czy na pewno chcesz trwale usunąć te {0} elementy?</ConfirmDeleteText>
<RecycleBinSizeText>Całkowity rozmiar {0}, {1} elementów</RecycleBinSizeText>
</pl>
<pt-BR>
<RecycleBinEmptyText>Lixeira está vazia</RecycleBinEmptyText>
<RecycleBinButton>Esvaziar lixeira</RecycleBinButton>
<ConfirmDeleteText>Tem certeza de que deseja excluir permanentemente estes {0} itens?</ConfirmDeleteText>
<RecycleBinSizeText>Tamanho total {0}, {1} itens</RecycleBinSizeText>
</pt-BR>
<pt-PT>
<RecycleBinEmptyText>A reciclagem está vazia</RecycleBinEmptyText>
<RecycleBinButton>Esvaziar reciclagem</RecycleBinButton>
<ConfirmDeleteText>Tem a certeza que pretende eliminar permanentemente estes {0} itens?</ConfirmDeleteText>
<RecycleBinSizeText>Tamanho total {0}, {1} itens</RecycleBinSizeText>
</pt-PT>
<ru-RU>
<RecycleBinEmptyText>Корзина пуста</RecycleBinEmptyText>
<RecycleBinButton>Очистить корзину</RecycleBinButton>
<ConfirmDeleteText>Вы уверены, что хотите навсегда удалить эти {0} элементов?</ConfirmDeleteText>
<RecycleBinSizeText>Общий размер {0}, {1} элементов</RecycleBinSizeText>
</ru-RU>
<sk>
<RecycleBinEmptyText>Kôš je prázdny</RecycleBinEmptyText>
<RecycleBinButton>Vyprázdniť kôš</RecycleBinButton>
<ConfirmDeleteText>Ste si istý, že chcete natrvalo odstrániť týchto {0} položiek?</ConfirmDeleteText>
<RecycleBinSizeText>Celková veľkosť {0}, {1} položiek</RecycleBinSizeText>
</sk>
<tr-TR>
<RecycleBinEmptyText>Geri Dönüşüm Kutusu boş</RecycleBinEmptyText>
<RecycleBinButton>Geri Dönüşüm Kutusunu Boşalt</RecycleBinButton>
<ConfirmDeleteText>Bu {0} öğeyi kalıcı olarak silmek istediğinizden emin misiniz?</ConfirmDeleteText>
<RecycleBinSizeText>Toplam boyut {0}, {1} öğe</RecycleBinSizeText>
</tr-TR>
<uk-UA>
<RecycleBinEmptyText>Кошик порожній</RecycleBinEmptyText>
<RecycleBinButton>Очистити кошик</RecycleBinButton>
<ConfirmDeleteText>Ви впевнені, що хочете назавжди видалити ці {0} елементів?</ConfirmDeleteText>
<RecycleBinSizeText>Загальний розмір {0}, {1} елементів</RecycleBinSizeText>
</uk-UA>
<vi>
<RecycleBinEmptyText>Thùng rác trống</RecycleBinEmptyText>
<RecycleBinButton>Làm trống thùng rác</RecycleBinButton>
<ConfirmDeleteText>Bạn có chắc muốn xóa vĩnh viễn {0} mục này không?</ConfirmDeleteText>
<RecycleBinSizeText>Tổng kích thước {0}, {1} mục</RecycleBinSizeText>
</vi>
<en>
<RecycleBinEmptyText>Recycle Bin is empty</RecycleBinEmptyText>
<RecycleBinButton>Empty Recycle Bin</RecycleBinButton>

View File

@@ -1,52 +1,172 @@
<?xml version="1.0" encoding="utf-8"?>
<Translations>
<en>
<TOTAL_SIZE>Total Size</TOTAL_SIZE>
<FORMAT>Format</FORMAT>
<FORMAT_PROFILE>Format Profile</FORMAT_PROFILE>
<NAME>Name</NAME>
</en>
<ko>
<TOTAL_SIZE>전체 크기</TOTAL_SIZE>
<FORMAT>형식</FORMAT>
<FORMAT_PROFILE>형식 프로필</FORMAT_PROFILE>
<NAME>이름</NAME>
</ko>
<pt-BR>
<TOTAL_SIZE>Tamanho total</TOTAL_SIZE>
<FORMAT>Formato</FORMAT>
<FORMAT_PROFILE>Perfil do Formato</FORMAT_PROFILE>
<NAME>Nome</NAME>
</pt-BR>
<zh-CN>
<TOTAL_SIZE>总大小</TOTAL_SIZE>
<FORMAT>格式</FORMAT>
<FORMAT_PROFILE>格式配置</FORMAT_PROFILE>
<NAME>名称</NAME>
</zh-CN>
<zh-TW>
<TOTAL_SIZE>縂大小</TOTAL_SIZE>
<FORMAT>格式</FORMAT>
<FORMAT_PROFILE>格式設定</FORMAT_PROFILE>
<NAME>名稱</NAME>
</zh-TW>
<ja>
<TOTAL_SIZE>合計サイズ</TOTAL_SIZE>
<FORMAT>フォーマット</FORMAT>
<FORMAT_PROFILE>フォーマットプロファイル</FORMAT_PROFILE>
<NAME>名称</NAME>
</ja>
<de>
<TOTAL_SIZE>Gesamtgröße</TOTAL_SIZE>
<FORMAT>Format</FORMAT>
<FORMAT_PROFILE>Formatprofil</FORMAT_PROFILE>
<NAME>Name</NAME>
</de>
<sv>
<TOTAL_SIZE>Total storlek</TOTAL_SIZE>
<FORMAT>Format</FORMAT>
<FORMAT_PROFILE>Formatprofil</FORMAT_PROFILE>
<NAME>Namn</NAME>
</sv>
<ar>
<TOTAL_SIZE>الحجم الكلي</TOTAL_SIZE>
<FORMAT>التنسيق</FORMAT>
<FORMAT_PROFILE>ملف تعريف التنسيق</FORMAT_PROFILE>
<NAME>الاسم</NAME>
</ar>
<ca>
<TOTAL_SIZE>Mida total</TOTAL_SIZE>
<FORMAT>Format</FORMAT>
<FORMAT_PROFILE>Perfil de format</FORMAT_PROFILE>
<NAME>Nom</NAME>
</ca>
<el>
<TOTAL_SIZE>Συνολικό μέγεθος</TOTAL_SIZE>
<FORMAT>Μορφή</FORMAT>
<FORMAT_PROFILE>Προφίλ μορφής</FORMAT_PROFILE>
<NAME>Όνομα</NAME>
</el>
<es>
<TOTAL_SIZE>Tamaño total</TOTAL_SIZE>
<FORMAT>Formato</FORMAT>
<FORMAT_PROFILE>Perfil de formato</FORMAT_PROFILE>
<NAME>Nombre</NAME>
</es>
<fr>
<TOTAL_SIZE>Taille totale</TOTAL_SIZE>
<FORMAT>Format</FORMAT>
<FORMAT_PROFILE>Profil du format</FORMAT_PROFILE>
<NAME>Nom</NAME>
</fr>
<he>
<TOTAL_SIZE>גודל כולל</TOTAL_SIZE>
<FORMAT>פורמט</FORMAT>
<FORMAT_PROFILE>פרופיל פורמט</FORMAT_PROFILE>
<NAME>שם</NAME>
</he>
<hi>
<TOTAL_SIZE>कुल आकार</TOTAL_SIZE>
<FORMAT>प्रारूप</FORMAT>
<FORMAT_PROFILE>प्रारूप प्रोफ़ाइल</FORMAT_PROFILE>
<NAME>नाम</NAME>
</hi>
<hu-HU>
<TOTAL_SIZE>Teljes méret</TOTAL_SIZE>
<FORMAT>Formátum</FORMAT>
<FORMAT_PROFILE>Formátum profil</FORMAT_PROFILE>
<NAME>Név</NAME>
</hu-HU>
<id-ID>
<TOTAL_SIZE>Ukuran total</TOTAL_SIZE>
<FORMAT>Format</FORMAT>
<FORMAT_PROFILE>Profil Format</FORMAT_PROFILE>
<NAME>Nama</NAME>
</id-ID>
<it>
<TOTAL_SIZE>Dimensione totale</TOTAL_SIZE>
<FORMAT>Formato</FORMAT>
<FORMAT_PROFILE>Profilo formato</FORMAT_PROFILE>
<NAME>Nome</NAME>
</it>
<mr>
<TOTAL_SIZE>एकूण आकार</TOTAL_SIZE>
<FORMAT>स्वरूप</FORMAT>
<FORMAT_PROFILE>स्वरूप प्रोफाइल</FORMAT_PROFILE>
<NAME>नाव</NAME>
</mr>
<nb-NO>
<TOTAL_SIZE>Total størrelse</TOTAL_SIZE>
<FORMAT>Format</FORMAT>
<FORMAT_PROFILE>Formatprofil</FORMAT_PROFILE>
<NAME>Navn</NAME>
</nb-NO>
<nl-NL>
<TOTAL_SIZE>Totale grootte</TOTAL_SIZE>
<FORMAT>Formaat</FORMAT>
<FORMAT_PROFILE>Formaatprofiel</FORMAT_PROFILE>
<NAME>Naam</NAME>
</nl-NL>
<pl>
<TOTAL_SIZE>Całkowity rozmiar</TOTAL_SIZE>
<FORMAT>Format</FORMAT>
<FORMAT_PROFILE>Profil formatu</FORMAT_PROFILE>
<NAME>Nazwa</NAME>
</pl>
<pt-PT>
<TOTAL_SIZE>Tamanho total</TOTAL_SIZE>
<FORMAT>Formato</FORMAT>
<FORMAT_PROFILE>Perfil de formato</FORMAT_PROFILE>
<NAME>Nome</NAME>
</pt-PT>
<ru-RU>
<TOTAL_SIZE>Общий размер</TOTAL_SIZE>
<FORMAT>Формат</FORMAT>
<FORMAT_PROFILE>Профиль формата</FORMAT_PROFILE>
<NAME>Имя</NAME>
</ru-RU>
<sk>
<TOTAL_SIZE>Celková veľkosť</TOTAL_SIZE>
<FORMAT>Formát</FORMAT>
<FORMAT_PROFILE>Profil formátu</FORMAT_PROFILE>
<NAME>Názov</NAME>
</sk>
<tr-TR>
<TOTAL_SIZE>Toplam boyut</TOTAL_SIZE>
<FORMAT>Biçim</FORMAT>
<FORMAT_PROFILE>Biçim profili</FORMAT_PROFILE>
<NAME>Ad</NAME>
</tr-TR>
<uk-UA>
<TOTAL_SIZE>Загальний розмір</TOTAL_SIZE>
<FORMAT>Формат</FORMAT>
<FORMAT_PROFILE>Профіль формату</FORMAT_PROFILE>
<NAME>Назва</NAME>
</uk-UA>
<vi>
<TOTAL_SIZE>Tổng kích thước</TOTAL_SIZE>
<FORMAT>Định dạng</FORMAT>
<FORMAT_PROFILE>Hồ sơ định dạng</FORMAT_PROFILE>
<NAME>Tên</NAME>
</vi>
<en>
<TOTAL_SIZE>Total Size</TOTAL_SIZE>
<FORMAT>Format</FORMAT>
<FORMAT_PROFILE>Format Profile</FORMAT_PROFILE>
<NAME>Name</NAME>
</en>
<ko>
<TOTAL_SIZE>전체 크기</TOTAL_SIZE>
<FORMAT>형식</FORMAT>
<FORMAT_PROFILE>형식 프로필</FORMAT_PROFILE>
<NAME>이름</NAME>
</ko>
<pt-BR>
<TOTAL_SIZE>Tamanho total</TOTAL_SIZE>
<FORMAT>Formato</FORMAT>
<FORMAT_PROFILE>Perfil do Formato</FORMAT_PROFILE>
<NAME>Nome</NAME>
</pt-BR>
<zh-CN>
<TOTAL_SIZE>总大小</TOTAL_SIZE>
<FORMAT>格式</FORMAT>
<FORMAT_PROFILE>格式配置</FORMAT_PROFILE>
<NAME>名称</NAME>
</zh-CN>
<zh-TW>
<TOTAL_SIZE>縂大小</TOTAL_SIZE>
<FORMAT>格式</FORMAT>
<FORMAT_PROFILE>格式設定</FORMAT_PROFILE>
<NAME>名稱</NAME>
</zh-TW>
<ja>
<TOTAL_SIZE>合計サイズ</TOTAL_SIZE>
<FORMAT>フォーマット</FORMAT>
<FORMAT_PROFILE>フォーマットプロファイル</FORMAT_PROFILE>
<NAME>名称</NAME>
</ja>
<de>
<TOTAL_SIZE>Gesamtgröße</TOTAL_SIZE>
<FORMAT>Format</FORMAT>
<FORMAT_PROFILE>Formatprofil</FORMAT_PROFILE>
<NAME>Name</NAME>
</de>
<sv>
<TOTAL_SIZE>Total storlek</TOTAL_SIZE>
<FORMAT>Format</FORMAT>
<FORMAT_PROFILE>Formatprofil</FORMAT_PROFILE>
<NAME>Namn</NAME>
</sv>
</Translations>

View File

@@ -1,6 +1,72 @@
<?xml version="1.0" encoding="utf-8"?>
<Translations>
<ar>
<SAMPLE_TEXT>أبجد هوز حطي كلمن سعفص قرشت ثخذ ضظغ 0123456789</SAMPLE_TEXT>
</ar>
<ca>
<SAMPLE_TEXT>El llop marró ràpid salta sobre el gos mandrós. 1234567890</SAMPLE_TEXT>
</ca>
<el>
<SAMPLE_TEXT>Ταχίστη αλεπού πηδάει πάνω από το τεμπέλικο σκυλί. 1234567890</SAMPLE_TEXT>
</el>
<es>
<SAMPLE_TEXT>El veloz murciélago hindú comía feliz cardillo y kiwi. 1234567890</SAMPLE_TEXT>
</es>
<fr>
<SAMPLE_TEXT>Portez ce vieux whisky au juge blond qui fume. 1234567890</SAMPLE_TEXT>
</fr>
<he>
<SAMPLE_TEXT>דג סקרן שט בים מאוכזב ולפתע מצא לו חברה. 0123456789</SAMPLE_TEXT>
</he>
<hi>
<SAMPLE_TEXT>तेज भूरी लोमड़ी आलसी कुत्ते के ऊपर कूद गई। 0123456789</SAMPLE_TEXT>
</hi>
<hu-HU>
<SAMPLE_TEXT>Árvíztűrő tükörfúrógép. 1234567890</SAMPLE_TEXT>
</hu-HU>
<id-ID>
<SAMPLE_TEXT>Sembilan belas pohon besar tumbuh di pinggir jalan. 1234567890</SAMPLE_TEXT>
</id-ID>
<it>
<SAMPLE_TEXT>Ma la volpe col suo balzo ha raggiunto il quieto Fido. 1234567890</SAMPLE_TEXT>
</it>
<ja>
<SAMPLE_TEXT>いろはにほへと ちりぬるを 0123456789</SAMPLE_TEXT>
</ja>
<mr>
<SAMPLE_TEXT>चंपक लाल गब्बर सिंह झोपडीत बसला आहे. 0123456789</SAMPLE_TEXT>
</mr>
<nb-NO>
<SAMPLE_TEXT>Vår sære Zulu fra badeøya spilte jo whist og quickstep. 1234567890</SAMPLE_TEXT>
</nb-NO>
<nl-NL>
<SAMPLE_TEXT>Pa's wijze lynx bezag vroom het fikse aquaduct. 1234567890</SAMPLE_TEXT>
</nl-NL>
<pl>
<SAMPLE_TEXT>Pójdźże, kiń tę chmurną z sylabą, gęślą jaźń. 1234567890</SAMPLE_TEXT>
</pl>
<pt-BR>
<SAMPLE_TEXT>Véio zebu, câmelo, quati, jabuti, foca, índio, urso, gnu, raposa, cão. 1234567890</SAMPLE_TEXT>
</pt-BR>
<pt-PT>
<SAMPLE_TEXT>Um pequeno jabuti xereta viu dez cegonhas felizes. 1234567890</SAMPLE_TEXT>
</pt-PT>
<ru-RU>
<SAMPLE_TEXT>Съешь же ещё этих мягких французских булок да выпей чаю. 0123456789</SAMPLE_TEXT>
</ru-RU>
<sk>
<SAMPLE_TEXT>Kŕdeľ ďatľov učí mĺkveho koňa občas žrať trávu. 1234567890</SAMPLE_TEXT>
</sk>
<tr-TR>
<SAMPLE_TEXT>Pijamalı hasta yağız şoföre çabucak güvendi. 1234567890</SAMPLE_TEXT>
</tr-TR>
<uk-UA>
<SAMPLE_TEXT>Фраза, що містить всі літери абетки: їжак чує шум гілки. 0123456789</SAMPLE_TEXT>
</uk-UA>
<vi>
<SAMPLE_TEXT>Chú thích: Tôi yêu ngôn ngữ Việt Nam. 0123456789</SAMPLE_TEXT>
</vi>
<en>
<SAMPLE_TEXT>The quick brown fox jumped over the lazy dog. 1234567890</SAMPLE_TEXT>
</en>

View File

@@ -64,7 +64,7 @@ public class Plugin : IViewer
public void Prepare(string path, ContextObject context)
{
context.PreferredSize = new Size { Width = 800, Height = 800 };
context.PreferredSize = new Size { Width = 800, Height = 600 };
}
public void View(string path, ContextObject context)

View File

@@ -1,6 +1,48 @@
<?xml version="1.0" encoding="utf-8"?>
<Translations>
<ca>
<WEBVIEW2_NOT_AVAILABLE>Cal instal·lar Microsoft Edge WebView2 per veure aquest fitxer.&#10;Feu clic aquí per descarregar-lo.</WEBVIEW2_NOT_AVAILABLE>
</ca>
<he>
<WEBVIEW2_NOT_AVAILABLE>צפייה בקובץ זה דורשת התקנת Microsoft Edge WebView2.&#10;לחץ כאן להורדה.</WEBVIEW2_NOT_AVAILABLE>
</he>
<hi>
<WEBVIEW2_NOT_AVAILABLE>इस फ़ाइल को देखने के लिए Microsoft Edge WebView2 इंस्टॉल होना आवश्यक है।&#10;डाउनलोड करने के लिए यहां क्लिक करें.</WEBVIEW2_NOT_AVAILABLE>
</hi>
<hu-HU>
<WEBVIEW2_NOT_AVAILABLE>A fájl megtekintéséhez telepíteni kell a Microsoft Edge WebView2-t.&#10;Kattintson ide a letöltéshez.</WEBVIEW2_NOT_AVAILABLE>
</hu-HU>
<id-ID>
<WEBVIEW2_NOT_AVAILABLE>Melihat file ini memerlukan Microsoft Edge WebView2 terinstal.&#10;Klik di sini untuk mengunduhnya.</WEBVIEW2_NOT_AVAILABLE>
</id-ID>
<mr>
<WEBVIEW2_NOT_AVAILABLE>या फाइलचे दृश्य Microsoft Edge WebView2 स्थापित असणे आवश्यक आहे.&#10;डाउनलोडसाठी येथे क्लिक करा.</WEBVIEW2_NOT_AVAILABLE>
</mr>
<nb-NO>
<WEBVIEW2_NOT_AVAILABLE>For å vise denne filen må Microsoft Edge WebView2 være installert.&#10;Klikk her for å laste ned.</WEBVIEW2_NOT_AVAILABLE>
</nb-NO>
<nl-NL>
<WEBVIEW2_NOT_AVAILABLE>Voor het bekijken van dit bestand moet Microsoft Edge WebView2 geïnstalleerd zijn.&#10;Klik hier om te downloaden.</WEBVIEW2_NOT_AVAILABLE>
</nl-NL>
<pt-BR>
<WEBVIEW2_NOT_AVAILABLE>Para visualizar este arquivo, é necessário instalar o Microsoft Edge WebView2.&#10;Clique aqui para baixar.</WEBVIEW2_NOT_AVAILABLE>
</pt-BR>
<pt-PT>
<WEBVIEW2_NOT_AVAILABLE>Para visualizar este ficheiro, é necessário instalar o Microsoft Edge WebView2.&#10;Clique aqui para descarregar.</WEBVIEW2_NOT_AVAILABLE>
</pt-PT>
<ru-RU>
<WEBVIEW2_NOT_AVAILABLE>Для просмотра этого файла требуется установка Microsoft Edge WebView2.&#10;Нажмите здесь, чтобы скачать.</WEBVIEW2_NOT_AVAILABLE>
</ru-RU>
<sk>
<WEBVIEW2_NOT_AVAILABLE>Na zobrazenie tohto súboru je potrebné nainštalovať Microsoft Edge WebView2.&#10;Kliknite sem pre stiahnutie.</WEBVIEW2_NOT_AVAILABLE>
</sk>
<tr-TR>
<WEBVIEW2_NOT_AVAILABLE>Bu dosyayı görüntülemek için Microsoft Edge WebView2'nin yüklü olması gerekir.&#10;İndirmek için buraya tıklayın.</WEBVIEW2_NOT_AVAILABLE>
</tr-TR>
<vi>
<WEBVIEW2_NOT_AVAILABLE>Để xem tệp này, cần cài đặt Microsoft Edge WebView2.&#10;Nhấn vào đây để tải về.</WEBVIEW2_NOT_AVAILABLE>
</vi>
<en>
<WEBVIEW2_NOT_AVAILABLE>Viewing this file requires Microsoft Edge WebView2 to be installed.&#10;Click here to download it.</WEBVIEW2_NOT_AVAILABLE>
</en>

View File

@@ -22,12 +22,25 @@ namespace QuickLook.Plugin.ImageViewer.Webview.Lottie;
internal static class LottieDetector
{
public static bool IsVaild(string path)
public static bool IsVaildFile(string path)
{
try
{
var jsonString = File.ReadAllText(path);
return IsVaildContent(jsonString);
}
catch
{
// If any exception occurs, assume it's not a valid Lottie file
}
return false;
}
public static bool IsVaildContent(string jsonString)
{
try
{
// No exception will be thrown here
var jsonLottie = LottieParser.Parse<Dictionary<string, object>>(jsonString);

View File

@@ -0,0 +1,42 @@
// Copyright © 2017-2025 QL-Win Contributors
//
// This file is part of QuickLook program.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
using QuickLook.Plugin.ImageViewer.Webview.Lottie;
namespace QuickLook.Plugin.ImageViewer.Webview.Tgs;
internal static class TgsDetector
{
public static bool IsValidFile(string path)
{
try
{
// Extract JSON content from gzipped TGS file
var jsonString = TgsExtractor.GetJsonContent(path);
return IsVaildContent(jsonString);
}
catch
{
// If any exception occurs, assume it's not a valid TGS file
}
return false;
}
public static bool IsVaildContent(string jsonString)
=> LottieDetector.IsVaildContent(jsonString);
}

View File

@@ -0,0 +1,33 @@
// Copyright © 2017-2025 QL-Win Contributors
//
// This file is part of QuickLook program.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
using System.IO;
using System.IO.Compression;
using System.Text;
namespace QuickLook.Plugin.ImageViewer.Webview.Tgs;
internal static class TgsExtractor
{
public static string GetJsonContent(string path)
{
using var fileStream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite | FileShare.Delete);
using var gzipStream = new GZipStream(fileStream, CompressionMode.Decompress);
using var reader = new StreamReader(gzipStream, Encoding.UTF8);
return reader.ReadToEnd();
}
}

View File

@@ -0,0 +1,92 @@
// Copyright © 2017-2025 QL-Win Contributors
//
// This file is part of QuickLook program.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
using Microsoft.Web.WebView2.Core;
using QuickLook.Plugin.ImageViewer.Webview.Svg;
using System;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace QuickLook.Plugin.ImageViewer.Webview.Tgs;
public class TgsImagePanel : SvgImagePanel
{
public override void Preview(string path)
{
FallbackPath = Path.GetDirectoryName(path);
ObjectForScripting ??= new TgsScriptHandler(path);
_homePage = _resources["/lottie2html.html"];
NavigateToUri(new Uri("file://quicklook/"));
}
protected override void WebView_WebResourceRequested(object sender, CoreWebView2WebResourceRequestedEventArgs args)
{
try
{
var requestedUri = new Uri(args.Request.Uri);
if ((requestedUri.Scheme == "https" || requestedUri.Scheme == "http")
&& requestedUri.AbsolutePath.EndsWith(".tgs", StringComparison.OrdinalIgnoreCase))
{
var localPath = Uri.UnescapeDataString($"{requestedUri.Authority}:{requestedUri.AbsolutePath}".Replace('/', '\\'));
if (localPath.StartsWith(_fallbackPath, StringComparison.OrdinalIgnoreCase))
{
if (File.Exists(localPath))
{
var content = TgsExtractor.GetJsonContent(localPath);
byte[] byteArray = Encoding.UTF8.GetBytes(content);
var stream = new MemoryStream(byteArray);
var response = _webView.CoreWebView2.Environment.CreateWebResourceResponse(
stream, 200, "OK",
$"""
Access-Control-Allow-Origin: *
Content-Type: {MimeTypes.GetMimeType()}
"""
);
args.Response = response;
return;
}
}
}
}
catch (Exception e)
{
// We don't need to feel burdened by any exceptions
Debug.WriteLine(e);
}
base.WebView_WebResourceRequested(sender, args);
}
}
[ClassInterface(ClassInterfaceType.AutoDual)]
[ComVisible(true)]
public sealed class TgsScriptHandler(string path)
{
public string Path { get; } = path;
public async Task<string> GetPath()
{
return await Task.FromResult(new Uri(Path).AbsolutePath);
}
}

View File

@@ -0,0 +1,62 @@
// Copyright © 2017-2025 QL-Win Contributors
//
// This file is part of QuickLook program.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
using QuickLook.Plugin.ImageViewer.Webview.Lottie;
using System.Collections.Generic;
using System.IO;
using System.Windows;
namespace QuickLook.Plugin.ImageViewer.Webview.Tgs;
public class TgsMetaProvider(string path) : IWebMetaProvider
{
private readonly string _path = path;
private Size _size = Size.Empty;
public Size GetSize()
{
if (_size != Size.Empty)
{
return _size;
}
if (!File.Exists(_path))
{
return _size;
}
try
{
var jsonString = TgsExtractor.GetJsonContent(_path);
var jsonLottie = LottieParser.Parse<Dictionary<string, object>>(jsonString);
if (jsonLottie.ContainsKey("w")
&& jsonLottie.ContainsKey("h")
&& double.TryParse(jsonLottie["w"].ToString(), out double width)
&& double.TryParse(jsonLottie["h"].ToString(), out double height))
{
return _size = new Size(width, height);
}
}
catch
{
// That's fine, just return the default size.
}
return new Size(800, 600);
}
}

View File

@@ -20,6 +20,7 @@ using QuickLook.Common.Plugin;
using QuickLook.Plugin.ImageViewer.Webview.Lottie;
using QuickLook.Plugin.ImageViewer.Webview.Svg;
using QuickLook.Plugin.ImageViewer.Webview.Svga;
using QuickLook.Plugin.ImageViewer.Webview.Tgs;
using System;
using System.IO;
using System.Windows;
@@ -37,7 +38,8 @@ internal static class WebHandler
{
".svg" => SettingHelper.Get("RenderSvgWeb", true, "QuickLook.Plugin.ImageViewer"),
".svga" or ".lottie" => true,
".json" => LottieDetector.IsVaild(path), // Check for Lottie files
".tgs" => TgsDetector.IsValidFile(path), // Check for TGS files
".json" => LottieDetector.IsVaildFile(path), // Check for Lottie files
_ => false,
};
}
@@ -47,7 +49,7 @@ internal static class WebHandler
string ext = Path.GetExtension(path).ToLower();
if (ext == ".svg" || ext == ".svga"
|| ext == ".lottie" || ext == ".json")
|| ext == ".lottie" || ext == ".tgs" || ext == ".json")
{
if (ext == ".svg")
{
@@ -63,6 +65,7 @@ internal static class WebHandler
".svg" => new SvgMetaProvider(path),
".svga" => new SvgaMetaProvider(path),
".lottie" or ".json" => new LottieMetaProvider(path),
".tgs" => new TgsMetaProvider(path),
_ => throw new NotSupportedException($"Unsupported file type: {ext}")
};
var sizeSvg = metaWeb.GetSize();
@@ -85,7 +88,8 @@ internal static class WebHandler
string ext = Path.GetExtension(path).ToLower();
if (ext == ".svg" || ext == ".svga"
|| ext == ".lottie" || ext == ".json")
|| ext == ".lottie" || ext == ".json"
|| ext == ".tgs")
{
if (ext == ".svg")
{
@@ -101,6 +105,7 @@ internal static class WebHandler
".svg" => new SvgImagePanel(),
".svga" => new SvgaImagePanel(metaWeb),
".lottie" or ".json" => new LottieImagePanel(),
".tgs" => new TgsImagePanel(),
_ => throw new NotSupportedException($"Unsupported file type: {ext}")
};

View File

@@ -1,4 +1,21 @@
using MediaInfoLib;
// Copyright © 2017-2025 QL-Win Contributors
//
// This file is part of QuickLook program.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
using MediaInfoLib;
using System.ComponentModel.Composition;
namespace QuickLook.Plugin.MediaInfoViewer;

View File

@@ -0,0 +1,54 @@
// Copyright © 2017-2025 QL-Win Contributors
//
// This file is part of QuickLook program.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
using QuickLook.Common.Commands;
using QuickLook.Common.Helpers;
using QuickLook.Common.Plugin.MoreMenu;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Windows.Input;
namespace QuickLook.Plugin.MediaInfoViewer;
public partial class Plugin
{
public ICommand ShowWithMediaInfoCommand { get; }
public Plugin()
{
ShowWithMediaInfoCommand = new RelayCommand(ShowWithMediaInfo);
}
public IEnumerable<IMenuItem> GetMenuItems()
{
string translationFile = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Translations.config");
yield return new MoreMenuItem()
{
Icon = "\xea69",
Header = TranslationHelper.Get("MW_ShowMediaInfo", translationFile),
MenuItems = null,
Command = ShowWithMediaInfoCommand,
};
}
public void ShowWithMediaInfo()
{
PluginHelper.InvokePluginPreview("QuickLook.Plugin.MediaInfoViewer");
}
}

View File

@@ -18,7 +18,9 @@
using MediaInfoLib;
using QuickLook.Common.Helpers;
using QuickLook.Common.Plugin;
using QuickLook.Common.Plugin.MoreMenu;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Windows;
@@ -26,12 +28,14 @@ using System.Windows.Media;
namespace QuickLook.Plugin.MediaInfoViewer;
public class Plugin : IViewer
public partial class Plugin : IViewer, IMoreMenuExtended
{
private TextViewerPanel _tvp;
public int Priority => 0;
public IEnumerable<IMenuItem> MenuItems => GetMenuItems();
public void Init()
{
}

View File

@@ -0,0 +1,88 @@
<?xml version="1.0" encoding="utf-8"?>
<Translations>
<ar>
<MW_ShowMediaInfo>عرض معلومات الوسائط</MW_ShowMediaInfo>
</ar>
<ca>
<MW_ShowMediaInfo>Mostra informació multimèdia</MW_ShowMediaInfo>
</ca>
<de>
<MW_ShowMediaInfo>Medieninformationen anzeigen</MW_ShowMediaInfo>
</de>
<el>
<MW_ShowMediaInfo>Εμφάνιση πληροφοριών πολυμέσων</MW_ShowMediaInfo>
</el>
<en>
<MW_ShowMediaInfo>Show Media Info</MW_ShowMediaInfo>
</en>
<es>
<MW_ShowMediaInfo>Mostrar información multimedia</MW_ShowMediaInfo>
</es>
<fr>
<MW_ShowMediaInfo>Afficher les informations du média</MW_ShowMediaInfo>
</fr>
<he>
<MW_ShowMediaInfo>הצג מידע מדיה</MW_ShowMediaInfo>
</he>
<hi>
<MW_ShowMediaInfo>मीडिया जानकारी दिखाएँ</MW_ShowMediaInfo>
</hi>
<hu-HU>
<MW_ShowMediaInfo>Média információk megjelenítése</MW_ShowMediaInfo>
</hu-HU>
<id-ID>
<MW_ShowMediaInfo>Tampilkan Info Media</MW_ShowMediaInfo>
</id-ID>
<it>
<MW_ShowMediaInfo>Mostra informazioni multimediali</MW_ShowMediaInfo>
</it>
<ja>
<MW_ShowMediaInfo>メディア情報を表示</MW_ShowMediaInfo>
</ja>
<ko>
<MW_ShowMediaInfo>미디어 정보 표시</MW_ShowMediaInfo>
</ko>
<mr>
<MW_ShowMediaInfo>मीडिया माहिती दर्शवा</MW_ShowMediaInfo>
</mr>
<nb-NO>
<MW_ShowMediaInfo>Vis medieinformasjon</MW_ShowMediaInfo>
</nb-NO>
<nl-NL>
<MW_ShowMediaInfo>Toon mediainformatie</MW_ShowMediaInfo>
</nl-NL>
<pl>
<MW_ShowMediaInfo>Pokaż informacje o mediach</MW_ShowMediaInfo>
</pl>
<pt-BR>
<MW_ShowMediaInfo>Mostrar informações de mídia</MW_ShowMediaInfo>
</pt-BR>
<pt-PT>
<MW_ShowMediaInfo>Mostrar informações de mídia</MW_ShowMediaInfo>
</pt-PT>
<ru-RU>
<MW_ShowMediaInfo>Показать информацию о медиа</MW_ShowMediaInfo>
</ru-RU>
<sk>
<MW_ShowMediaInfo>Zobraziť informácie o médiu</MW_ShowMediaInfo>
</sk>
<sv>
<MW_ShowMediaInfo>Visa mediainformation</MW_ShowMediaInfo>
</sv>
<tr-TR>
<MW_ShowMediaInfo>Medya bilgisini göster</MW_ShowMediaInfo>
</tr-TR>
<uk-UA>
<MW_ShowMediaInfo>Показати інформацію про медіа</MW_ShowMediaInfo>
</uk-UA>
<vi>
<MW_ShowMediaInfo>Hiển thị thông tin phương tiện</MW_ShowMediaInfo>
</vi>
<zh-CN>
<MW_ShowMediaInfo>显示媒体信息</MW_ShowMediaInfo>
</zh-CN>
<zh-TW>
<MW_ShowMediaInfo>顯示媒體資訊</MW_ShowMediaInfo>
</zh-TW>
</Translations>

View File

@@ -71,10 +71,4 @@
</Compile>
</ItemGroup>
<ItemGroup>
<None Update="Translations.config">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>

View File

@@ -1,6 +1,5 @@
using Microsoft.Win32;
using System;
using System.IO;
using System.Security.Principal;
namespace QuickLook.Plugin.OfficeViewer;

View File

@@ -1,64 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Translations>
<en>
<RecycleBinEmptyText>Recycle Bin is empty</RecycleBinEmptyText>
<RecycleBinButton>Empty Recycle Bin</RecycleBinButton>
<ConfirmDeleteText>Are you sure you want to permanently delete these {0} item(s)?</ConfirmDeleteText>
<RecycleBinSizeText>Total size {0}, {1} items</RecycleBinSizeText>
</en>
<ko>
<RecycleBinEmptyText>휴지통이 비어 있습니다</RecycleBinEmptyText>
<RecycleBinButton>휴지통 비우기</RecycleBinButton>
<ConfirmDeleteText>{0}개 항목을 영구적으로 삭제하시겠습니까?</ConfirmDeleteText>
<RecycleBinSizeText>전체 크기 {0}, {1}개 항목</RecycleBinSizeText>
</ko>
<zh-CN>
<RecycleBinEmptyText>回收站是空的</RecycleBinEmptyText>
<RecycleBinButton>清空回收站</RecycleBinButton>
<ConfirmDeleteText>您确定要永久删除这 {0} 个项目吗?</ConfirmDeleteText>
<RecycleBinSizeText>总大小 {0},共 {1} 个项目</RecycleBinSizeText>
</zh-CN>
<zh-TW>
<RecycleBinEmptyText>回收站是空的</RecycleBinEmptyText>
<RecycleBinButton>清空回收站</RecycleBinButton>
<ConfirmDeleteText>您確定要永久刪除這 {0} 個項目嗎?</ConfirmDeleteText>
<RecycleBinSizeText>總大小 {0},共 {1} 個項目</RecycleBinSizeText>
</zh-TW>
<ja>
<RecycleBinEmptyText>ごみ箱は空です</RecycleBinEmptyText>
<RecycleBinButton>ごみ箱を空にする</RecycleBinButton>
<ConfirmDeleteText>これらの {0} 項目を完全に削除してもよろしいですか?</ConfirmDeleteText>
<RecycleBinSizeText>合計サイズ {0}、{1} 項目</RecycleBinSizeText>
</ja>
<ko>
<RecycleBinEmptyText>휴지통이 비어 있습니다</RecycleBinEmptyText>
<RecycleBinButton>휴지통 비우기</RecycleBinButton>
<ConfirmDeleteText>{0}개의 항목을 영구적으로 삭제하시겠습니까?</ConfirmDeleteText>
<RecycleBinSizeText>총 크기 {0}, 총 {1}개 항목</RecycleBinSizeText>
</ko>
<fr>
<RecycleBinEmptyText>La corbeille est vide</RecycleBinEmptyText>
<RecycleBinButton>Vider la corbeille</RecycleBinButton>
<ConfirmDeleteText>Êtes-vous sûr de vouloir supprimer définitivement ces {0} élément(s) ?</ConfirmDeleteText>
<RecycleBinSizeText>Taille totale {0}, {1} éléments</RecycleBinSizeText>
</fr>
<de>
<RecycleBinEmptyText>Der Papierkorb ist leer</RecycleBinEmptyText>
<RecycleBinButton>Papierkorb leeren</RecycleBinButton>
<ConfirmDeleteText>Möchten Sie diese {0} Elemente wirklich dauerhaft löschen?</ConfirmDeleteText>
<RecycleBinSizeText>Gesamtgröße {0}, {1} Elemente</RecycleBinSizeText>
</de>
<es>
<RecycleBinEmptyText>La papelera está vacía</RecycleBinEmptyText>
<RecycleBinButton>Vaciar papelera</RecycleBinButton>
<ConfirmDeleteText>¿Está seguro de que desea eliminar permanentemente estos {0} elemento(s)?</ConfirmDeleteText>
<RecycleBinSizeText>Tamaño total {0}, {1} elementos</RecycleBinSizeText>
</es>
<sv>
<RecycleBinEmptyText>Papperskorgen är tom</RecycleBinEmptyText>
<RecycleBinButton>Töm papperskorgen</RecycleBinButton>
<ConfirmDeleteText>Vill du ta bort de här {0} objekten permanent?</ConfirmDeleteText>
<RecycleBinSizeText>Total storlek: {0} ({1} objekt)</RecycleBinSizeText>
</sv>
</Translations>

View File

@@ -1,6 +1,146 @@
<?xml version="1.0" encoding="utf-8"?>
<Translations>
<ar>
<PW_Title>أدخل كلمة المرور</PW_Title>
<Pw_Hint>هذا الملف محمي بكلمة مرور. الرجاء إدخال كلمة المرور لفتحه.</Pw_Hint>
<PW_Error>تحقق من كلمة المرور</PW_Error>
<BTN_OpenFile>افتح الملف</BTN_OpenFile>
<BTN_Cancel>إلغاء</BTN_Cancel>
</ar>
<ca>
<PW_Title>Introduïu la contrasenya</PW_Title>
<Pw_Hint>Aquest fitxer està protegit amb contrasenya. Introduïu la contrasenya per obrir-lo.</Pw_Hint>
<PW_Error>Comproveu la contrasenya</PW_Error>
<BTN_OpenFile>Obre el fitxer</BTN_OpenFile>
<BTN_Cancel>Cancel·la</BTN_Cancel>
</ca>
<el>
<PW_Title>Εισάγετε τον κωδικό πρόσβασης</PW_Title>
<Pw_Hint>Αυτό το αρχείο προστατεύεται με κωδικό πρόσβασης. Εισάγετε τον κωδικό για να το ανοίξετε.</Pw_Hint>
<PW_Error>Ελέγξτε τον κωδικό πρόσβασης</PW_Error>
<BTN_OpenFile>Άνοιγμα αρχείου</BTN_OpenFile>
<BTN_Cancel>Ακύρωση</BTN_Cancel>
</el>
<es>
<PW_Title>Introduzca la contraseña</PW_Title>
<Pw_Hint>Este archivo está protegido por contraseña. Introduzca la contraseña para abrirlo.</Pw_Hint>
<PW_Error>Compruebe su contraseña</PW_Error>
<BTN_OpenFile>Abrir archivo</BTN_OpenFile>
<BTN_Cancel>Cancelar</BTN_Cancel>
</es>
<fr>
<PW_Title>Entrez le mot de passe</PW_Title>
<Pw_Hint>Ce fichier est protégé par un mot de passe. Veuillez entrer le mot de passe pour l'ouvrir.</Pw_Hint>
<PW_Error>Vérifiez votre mot de passe</PW_Error>
<BTN_OpenFile>Ouvrir le fichier</BTN_OpenFile>
<BTN_Cancel>Annuler</BTN_Cancel>
</fr>
<he>
<PW_Title>הזן סיסמה</PW_Title>
<Pw_Hint>קובץ זה מוגן בסיסמה. אנא הזן את הסיסמה לפתיחת הקובץ.</Pw_Hint>
<PW_Error>בדוק את הסיסמה שלך</PW_Error>
<BTN_OpenFile>פתח קובץ</BTN_OpenFile>
<BTN_Cancel>ביטול</BTN_Cancel>
</he>
<hi>
<PW_Title>पासवर्ड दर्ज करें</PW_Title>
<Pw_Hint>यह फ़ाइल पासवर्ड से सुरक्षित है। कृपया फ़ाइल खोलने के लिए पासवर्ड दर्ज करें।</Pw_Hint>
<PW_Error>अपना पासवर्ड जांचें</PW_Error>
<BTN_OpenFile>फ़ाइल खोलें</BTN_OpenFile>
<BTN_Cancel>रद्द करें</BTN_Cancel>
</hi>
<hu-HU>
<PW_Title>Adja meg a jelszót</PW_Title>
<Pw_Hint>Ez a fájl jelszóval védett. Kérjük, adja meg a jelszót a megnyitáshoz.</Pw_Hint>
<PW_Error>Ellenőrizze a jelszót</PW_Error>
<BTN_OpenFile>Fájl megnyitása</BTN_OpenFile>
<BTN_Cancel>Mégse</BTN_Cancel>
</hu-HU>
<id-ID>
<PW_Title>Masukkan kata sandi</PW_Title>
<Pw_Hint>File ini dilindungi kata sandi. Silakan masukkan kata sandi untuk membuka file.</Pw_Hint>
<PW_Error>Periksa kata sandi Anda</PW_Error>
<BTN_OpenFile>Buka File</BTN_OpenFile>
<BTN_Cancel>Batal</BTN_Cancel>
</id-ID>
<it>
<PW_Title>Inserisci la password</PW_Title>
<Pw_Hint>Questo file è protetto da password. Inserisci la password per aprire il file.</Pw_Hint>
<PW_Error>Controlla la tua password</PW_Error>
<BTN_OpenFile>Apri file</BTN_OpenFile>
<BTN_Cancel>Annulla</BTN_Cancel>
</it>
<mr>
<PW_Title>पासवर्ड प्रविष्ट करा</PW_Title>
<Pw_Hint>ही फाइल पासवर्डने संरक्षित आहे. फाइल उघडण्यासाठी पासवर्ड प्रविष्ट करा.</Pw_Hint>
<PW_Error>आपला पासवर्ड तपासा</PW_Error>
<BTN_OpenFile>फाइल उघडा</BTN_OpenFile>
<BTN_Cancel>रद्द करा</BTN_Cancel>
</mr>
<nb-NO>
<PW_Title>Skriv inn passord</PW_Title>
<Pw_Hint>Denne filen er passordbeskyttet. Skriv inn passordet for å åpne filen.</Pw_Hint>
<PW_Error>Sjekk passordet ditt</PW_Error>
<BTN_OpenFile>Åpne fil</BTN_OpenFile>
<BTN_Cancel>Avbryt</BTN_Cancel>
</nb-NO>
<nl-NL>
<PW_Title>Voer wachtwoord in</PW_Title>
<Pw_Hint>Dit bestand is met een wachtwoord beveiligd. Voer het wachtwoord in om het bestand te openen.</Pw_Hint>
<PW_Error>Controleer uw wachtwoord</PW_Error>
<BTN_OpenFile>Bestand openen</BTN_OpenFile>
<BTN_Cancel>Annuleren</BTN_Cancel>
</nl-NL>
<pl>
<PW_Title>Wprowadź hasło</PW_Title>
<Pw_Hint>Ten plik jest chroniony hasłem. Wprowadź hasło, aby otworzyć plik.</Pw_Hint>
<PW_Error>Sprawdź swoje hasło</PW_Error>
<BTN_OpenFile>Otwórz plik</BTN_OpenFile>
<BTN_Cancel>Anuluj</BTN_Cancel>
</pl>
<pt-PT>
<PW_Title>Introduza a palavra-passe</PW_Title>
<Pw_Hint>Este ficheiro está protegido por palavra-passe. Introduza a palavra-passe para abrir o ficheiro.</Pw_Hint>
<PW_Error>Verifique a sua palavra-passe</PW_Error>
<BTN_OpenFile>Abrir ficheiro</BTN_OpenFile>
<BTN_Cancel>Cancelar</BTN_Cancel>
</pt-PT>
<ru-RU>
<PW_Title>Введите пароль</PW_Title>
<Pw_Hint>Этот файл защищён паролем. Пожалуйста, введите пароль для открытия файла.</Pw_Hint>
<PW_Error>Проверьте свой пароль</PW_Error>
<BTN_OpenFile>Открыть файл</BTN_OpenFile>
<BTN_Cancel>Отмена</BTN_Cancel>
</ru-RU>
<sk>
<PW_Title>Zadajte heslo</PW_Title>
<Pw_Hint>Tento súbor je chránený heslom. Zadajte heslo na otvorenie súboru.</Pw_Hint>
<PW_Error>Skontrolujte heslo</PW_Error>
<BTN_OpenFile>Otvoriť súbor</BTN_OpenFile>
<BTN_Cancel>Zrušiť</BTN_Cancel>
</sk>
<tr-TR>
<PW_Title>Şifreyi girin</PW_Title>
<Pw_Hint>Bu dosya şifre ile korunmaktadır. Dosyayı açmak için lütfen şifreyi girin.</Pw_Hint>
<PW_Error>Şifrenizi kontrol edin</PW_Error>
<BTN_OpenFile>Dosyayı Aç</BTN_OpenFile>
<BTN_Cancel>İptal</BTN_Cancel>
</tr-TR>
<uk-UA>
<PW_Title>Введіть пароль</PW_Title>
<Pw_Hint>Цей файл захищено паролем. Введіть пароль для відкриття файлу.</Pw_Hint>
<PW_Error>Перевірте свій пароль</PW_Error>
<BTN_OpenFile>Відкрити файл</BTN_OpenFile>
<BTN_Cancel>Скасувати</BTN_Cancel>
</uk-UA>
<vi>
<PW_Title>Nhập mật khẩu</PW_Title>
<Pw_Hint>Tệp này được bảo vệ bằng mật khẩu. Vui lòng nhập mật khẩu để mở tệp.</Pw_Hint>
<PW_Error>Kiểm tra mật khẩu của bạn</PW_Error>
<BTN_OpenFile>Mở tệp</BTN_OpenFile>
<BTN_Cancel>Hủy</BTN_Cancel>
</vi>
<en>
<PW_Title>Enter Password</PW_Title>
<Pw_Hint>This file is password protected. Please enter the password to open the file.</Pw_Hint>

View File

@@ -1,44 +1,144 @@
<?xml version="1.0" encoding="utf-8"?>
<Translations>
<en>
<TOTAL_SIZE>Total Size</TOTAL_SIZE>
<FILE_VERSION>File Version</FILE_VERSION>
<PRODUCT_VERSION>Product Version</PRODUCT_VERSION>
</en>
<ko>
<TOTAL_SIZE>전체 크기</TOTAL_SIZE>
<FILE_VERSION>파일 버전</FILE_VERSION>
<PRODUCT_VERSION>제품 버전</PRODUCT_VERSION>
</ko>
<pt-BR>
<TOTAL_SIZE>Tamanho total</TOTAL_SIZE>
<FILE_VERSION>Versão do arquivo</FILE_VERSION>
<PRODUCT_VERSION>Versão do produto</PRODUCT_VERSION>
</pt-BR>
<zh-CN>
<TOTAL_SIZE>总大小</TOTAL_SIZE>
<FILE_VERSION>文件版本</FILE_VERSION>
<PRODUCT_VERSION>产品版本</PRODUCT_VERSION>
</zh-CN>
<zh-TW>
<TOTAL_SIZE>縂大小</TOTAL_SIZE>
<FILE_VERSION>檔案版本</FILE_VERSION>
<PRODUCT_VERSION>產品版本</PRODUCT_VERSION>
</zh-TW>
<ja>
<TOTAL_SIZE>合計サイズ</TOTAL_SIZE>
<FILE_VERSION>ファイルバージョン</FILE_VERSION>
<PRODUCT_VERSION>製品バージョン</PRODUCT_VERSION>
</ja>
<de>
<TOTAL_SIZE>Gesamtgröße</TOTAL_SIZE>
<FILE_VERSION>Dateiversion</FILE_VERSION>
<PRODUCT_VERSION>Produktversion</PRODUCT_VERSION>
</de>
<sv>
<TOTAL_SIZE>Total storlek</TOTAL_SIZE>
<FILE_VERSION>Filversion</FILE_VERSION>
<PRODUCT_VERSION>Produktversion</PRODUCT_VERSION>
</sv>
<ar>
<TOTAL_SIZE>الحجم الكلي</TOTAL_SIZE>
<FILE_VERSION>إصدار الملف</FILE_VERSION>
<PRODUCT_VERSION>إصدار المنتج</PRODUCT_VERSION>
</ar>
<ca>
<TOTAL_SIZE>Mida total</TOTAL_SIZE>
<FILE_VERSION>Versió del fitxer</FILE_VERSION>
<PRODUCT_VERSION>Versió del producte</PRODUCT_VERSION>
</ca>
<de>
<TOTAL_SIZE>Gesamtgröße</TOTAL_SIZE>
<FILE_VERSION>Dateiversion</FILE_VERSION>
<PRODUCT_VERSION>Produktversion</PRODUCT_VERSION>
</de>
<el>
<TOTAL_SIZE>Συνολικό μέγεθος</TOTAL_SIZE>
<FILE_VERSION>Έκδοση αρχείου</FILE_VERSION>
<PRODUCT_VERSION>Έκδοση προϊόντος</PRODUCT_VERSION>
</el>
<en>
<TOTAL_SIZE>Total Size</TOTAL_SIZE>
<FILE_VERSION>File Version</FILE_VERSION>
<PRODUCT_VERSION>Product Version</PRODUCT_VERSION>
</en>
<es>
<TOTAL_SIZE>Tamaño total</TOTAL_SIZE>
<FILE_VERSION>Versión de archivo</FILE_VERSION>
<PRODUCT_VERSION>Versión de producto</PRODUCT_VERSION>
</es>
<fr>
<TOTAL_SIZE>Taille totale</TOTAL_SIZE>
<FILE_VERSION>Version du fichier</FILE_VERSION>
<PRODUCT_VERSION>Version du produit</PRODUCT_VERSION>
</fr>
<he>
<TOTAL_SIZE>גודל כולל</TOTAL_SIZE>
<FILE_VERSION>גרסת קובץ</FILE_VERSION>
<PRODUCT_VERSION>גרסת מוצר</PRODUCT_VERSION>
</he>
<hi>
<TOTAL_SIZE>कुल आकार</TOTAL_SIZE>
<FILE_VERSION>फ़ाइल संस्करण</FILE_VERSION>
<PRODUCT_VERSION>उत्पाद संस्करण</PRODUCT_VERSION>
</hi>
<hu-HU>
<TOTAL_SIZE>Teljes méret</TOTAL_SIZE>
<FILE_VERSION>Fájlverzió</FILE_VERSION>
<PRODUCT_VERSION>Termékverzió</PRODUCT_VERSION>
</hu-HU>
<id-ID>
<TOTAL_SIZE>Ukuran total</TOTAL_SIZE>
<FILE_VERSION>Versi file</FILE_VERSION>
<PRODUCT_VERSION>Versi produk</PRODUCT_VERSION>
</id-ID>
<it>
<TOTAL_SIZE>Dimensione totale</TOTAL_SIZE>
<FILE_VERSION>Versione del file</FILE_VERSION>
<PRODUCT_VERSION>Versione del prodotto</PRODUCT_VERSION>
</it>
<ja>
<TOTAL_SIZE>合計サイズ</TOTAL_SIZE>
<FILE_VERSION>ファイルバージョン</FILE_VERSION>
<PRODUCT_VERSION>製品バージョン</PRODUCT_VERSION>
</ja>
<ko>
<TOTAL_SIZE>전체 크기</TOTAL_SIZE>
<FILE_VERSION>파일 버전</FILE_VERSION>
<PRODUCT_VERSION>제품 버전</PRODUCT_VERSION>
</ko>
<mr>
<TOTAL_SIZE>एकूण आकार</TOTAL_SIZE>
<FILE_VERSION>फाइल आवृत्ती</FILE_VERSION>
<PRODUCT_VERSION>उत्पादन आवृत्ती</PRODUCT_VERSION>
</mr>
<nb-NO>
<TOTAL_SIZE>Total størrelse</TOTAL_SIZE>
<FILE_VERSION>Filversjon</FILE_VERSION>
<PRODUCT_VERSION>Produktversjon</PRODUCT_VERSION>
</nb-NO>
<nl-NL>
<TOTAL_SIZE>Totale grootte</TOTAL_SIZE>
<FILE_VERSION>Bestandversie</FILE_VERSION>
<PRODUCT_VERSION>Productversie</PRODUCT_VERSION>
</nl-NL>
<pl>
<TOTAL_SIZE>Całkowity rozmiar</TOTAL_SIZE>
<FILE_VERSION>Wersja pliku</FILE_VERSION>
<PRODUCT_VERSION>Wersja produktu</PRODUCT_VERSION>
</pl>
<pt-BR>
<TOTAL_SIZE>Tamanho total</TOTAL_SIZE>
<FILE_VERSION>Versão do arquivo</FILE_VERSION>
<PRODUCT_VERSION>Versão do produto</PRODUCT_VERSION>
</pt-BR>
<pt-PT>
<TOTAL_SIZE>Tamanho total</TOTAL_SIZE>
<FILE_VERSION>Versão do ficheiro</FILE_VERSION>
<PRODUCT_VERSION>Versão do produto</PRODUCT_VERSION>
</pt-PT>
<ru-RU>
<TOTAL_SIZE>Общий размер</TOTAL_SIZE>
<FILE_VERSION>Версия файла</FILE_VERSION>
<PRODUCT_VERSION>Версия продукта</PRODUCT_VERSION>
</ru-RU>
<sk>
<TOTAL_SIZE>Celková veľkosť</TOTAL_SIZE>
<FILE_VERSION>Verzia súboru</FILE_VERSION>
<PRODUCT_VERSION>Verzia produktu</PRODUCT_VERSION>
</sk>
<sv>
<TOTAL_SIZE>Total storlek</TOTAL_SIZE>
<FILE_VERSION>Filversion</FILE_VERSION>
<PRODUCT_VERSION>Produktversion</PRODUCT_VERSION>
</sv>
<tr-TR>
<TOTAL_SIZE>Toplam boyut</TOTAL_SIZE>
<FILE_VERSION>Dosya sürümü</FILE_VERSION>
<PRODUCT_VERSION>Ürün sürümü</PRODUCT_VERSION>
</tr-TR>
<uk-UA>
<TOTAL_SIZE>Загальний розмір</TOTAL_SIZE>
<FILE_VERSION>Версія файлу</FILE_VERSION>
<PRODUCT_VERSION>Версія продукту</PRODUCT_VERSION>
</uk-UA>
<vi>
<TOTAL_SIZE>Tổng kích thước</TOTAL_SIZE>
<FILE_VERSION>Phiên bản tệp</FILE_VERSION>
<PRODUCT_VERSION>Phiên bản sản phẩm</PRODUCT_VERSION>
</vi>
<zh-CN>
<TOTAL_SIZE>总大小</TOTAL_SIZE>
<FILE_VERSION>文件版本</FILE_VERSION>
<PRODUCT_VERSION>产品版本</PRODUCT_VERSION>
</zh-CN>
<zh-TW>
<TOTAL_SIZE>總大小</TOTAL_SIZE>
<FILE_VERSION>檔案版本</FILE_VERSION>
<PRODUCT_VERSION>產品版本</PRODUCT_VERSION>
</zh-TW>
</Translations>

View File

@@ -31,6 +31,7 @@ public class FormatDetector
new MakefileDetector(),
new HostsDetector(),
new DockerfileDetector(),
new KrcDetector(),
];
public static IFormatDetector Confuse(string path, string text)
@@ -50,6 +51,26 @@ public class FormatDetector
.Where(detector => detector is not IConfusedFormatDetector && detector.Detect(path, text))
.FirstOrDefault();
}
public static bool Transfer(string path, out string text)
{
ITransferFormatDetector detector = Instance.TextDetectors
.Where(detector => detector is ITransferFormatDetector)
.Select(detector => detector as ITransferFormatDetector)
.FirstOrDefault();
text = null;
if (detector is null)
{
return false;
}
if (detector.Detect(path, null))
{
text = detector.Transfer(path);
return true;
}
return false;
}
}
public interface IFormatDetector
@@ -62,3 +83,8 @@ public interface IFormatDetector
}
public interface IConfusedFormatDetector : IFormatDetector;
public interface ITransferFormatDetector : IFormatDetector
{
public string Transfer(string path);
}

View File

@@ -0,0 +1,41 @@
// Copyright © 2017-2025 QL-Win Contributors
//
// This file is part of QuickLook program.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
using KRCLib;
using System;
using System.IO;
namespace QuickLook.Plugin.TextViewer.Detectors;
public sealed class KrcDetector : ITransferFormatDetector
{
public string Name => "INI";
public string Extension => ".ini"; // .krc is more like .ini than .lrc
public bool Detect(string path, string text)
{
_ = text;
return Path.GetExtension(path).Equals(".krc", StringComparison.OrdinalIgnoreCase);
}
public string Transfer(string path)
{
KRCLyrics krc = KRCLyrics.LoadFromFile(path);
return krc.SaveToString();
}
}

View File

@@ -66,6 +66,7 @@
<PackageReference Include="System.Memory" Version="4.6.3" />
<PackageReference Include="System.Buffers" Version="4.6.1" />
<PackageReference Include="System.Runtime.CompilerServices.Unsafe" Version="6.1.2" />
<PackageReference Include="KRCLib" Version="1.0.0" />
</ItemGroup>
<ItemGroup>

View File

@@ -34,6 +34,7 @@ using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Threading;
using Encoding = System.Text.Encoding;
namespace QuickLook.Plugin.TextViewer;
@@ -184,10 +185,17 @@ public partial class TextViewerPanel : TextEditor, IDisposable
const int maxLength = 5 * 1024 * 1024;
const int maxHighlightingLength = (int)(0.5d * 1024 * 1024);
var buffer = new MemoryStream();
bool fileTooLong;
bool fileTooLong = false;
using (var s = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
// Read file to memory stream
if (FormatDetector.Transfer(path, out string transferred))
{
byte[] bytes = Encoding.UTF8.GetBytes(transferred);
buffer.Write(bytes, 0, bytes.Length);
}
else
{
using var s = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
fileTooLong = s.Length > maxLength;
while (s.Position < s.Length && buffer.Length < maxLength)
{

View File

@@ -1,8 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<Translations>
<ar>
<Editor_FontFamily>Consolas</Editor_FontFamily>
<Editor_Copy>انسخ</Editor_Copy>
<Editor_SelectAll>حدد الكل</Editor_SelectAll>
</ar>
<ca>
<Editor_FontFamily>Consolas</Editor_FontFamily>
<Editor_Copy>Copia</Editor_Copy>
<Editor_SelectAll>Selecciona-ho tot</Editor_SelectAll>
</ca>
<de>
<Editor_FontFamily>Consolas</Editor_FontFamily>
@@ -46,12 +53,18 @@
</ko>
<nb-NO>
<Editor_FontFamily>Consolas</Editor_FontFamily>
<Editor_Copy>Kopier</Editor_Copy>
<Editor_SelectAll>Merk alt</Editor_SelectAll>
</nb-NO>
<nl-NL>
<Editor_FontFamily>Consolas</Editor_FontFamily>
<Editor_Copy>Kopiëren</Editor_Copy>
<Editor_SelectAll>Alles selecteren</Editor_SelectAll>
</nl-NL>
<pl>
<Editor_FontFamily>Consolas</Editor_FontFamily>
<Editor_Copy>Kopiuj</Editor_Copy>
<Editor_SelectAll>Zaznacz wszystko</Editor_SelectAll>
</pl>
<pt-BR>
<Editor_FontFamily>Consolas</Editor_FontFamily>
@@ -60,12 +73,18 @@
</pt-BR>
<pt-PT>
<Editor_FontFamily>Consolas</Editor_FontFamily>
<Editor_Copy>Copiar</Editor_Copy>
<Editor_SelectAll>Selecionar tudo</Editor_SelectAll>
</pt-PT>
<ru-RU>
<Editor_FontFamily>Consolas</Editor_FontFamily>
<Editor_Copy>Копировать</Editor_Copy>
<Editor_SelectAll>Выделить всё</Editor_SelectAll>
</ru-RU>
<tr-TR>
<Editor_FontFamily>Consolas</Editor_FontFamily>
<Editor_Copy>Kopyala</Editor_Copy>
<Editor_SelectAll>Tümünü seç</Editor_SelectAll>
</tr-TR>
<uk-UA>
<Editor_FontFamily>Consolas</Editor_FontFamily>
@@ -74,6 +93,8 @@
</uk-UA>
<vi>
<Editor_FontFamily>Consolas</Editor_FontFamily>
<Editor_Copy>Sao chép</Editor_Copy>
<Editor_SelectAll>Chọn tất cả</Editor_SelectAll>
</vi>
<zh-CN>
<Editor_FontFamily>Consolas,Microsoft Yahei UI,Microsoft Yahei,SimSun</Editor_FontFamily>
@@ -87,10 +108,34 @@
</zh-TW>
<mr>
<Editor_FontFamily>Consolas,Mangal,Nirmala UI</Editor_FontFamily>
<Editor_Copy>प्रतिलिपी करा</Editor_Copy>
<Editor_SelectAll>सर्व निवडा</Editor_SelectAll>
</mr>
<hi>
<Editor_FontFamily>Consolas,Mangal,Nirmala UI</Editor_FontFamily>
<Editor_Copy>कॉपी करें</Editor_Copy>
<Editor_SelectAll>सभी चुनें</Editor_SelectAll>
</hi>
<he>
<Editor_FontFamily>Consolas</Editor_FontFamily>
<Editor_Copy>העתק</Editor_Copy>
<Editor_SelectAll>בחר הכל</Editor_SelectAll>
</he>
<hu-HU>
<Editor_FontFamily>Consolas</Editor_FontFamily>
<Editor_Copy>Másolás</Editor_Copy>
<Editor_SelectAll>Mindet kijelöl</Editor_SelectAll>
</hu-HU>
<id-ID>
<Editor_FontFamily>Consolas</Editor_FontFamily>
<Editor_Copy>Salin</Editor_Copy>
<Editor_SelectAll>Pilih Semua</Editor_SelectAll>
</id-ID>
<sk>
<Editor_FontFamily>Consolas</Editor_FontFamily>
<Editor_Copy>Kopírovať</Editor_Copy>
<Editor_SelectAll>Označiť všetko</Editor_SelectAll>
</sk>
<el>
<Editor_FontFamily>Consolas</Editor_FontFamily>
<Editor_Copy>Aντιγραφή</Editor_Copy>

View File

@@ -1,4 +1,21 @@
using QuickLook.Common.ExtensionMethods;
// Copyright © 2017-2025 QL-Win Contributors
//
// This file is part of QuickLook program.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
using QuickLook.Common.ExtensionMethods;
using QuickLook.Plugin.VideoViewer.Extensions;
using System;
using System.Diagnostics;
@@ -51,6 +68,9 @@ internal static class CoverDataExtractor
/// <returns><see cref="BitmapSource"/> if successful; otherwise, null.</returns>
public static BitmapSource Extract(byte[] coverBytes)
{
// Supported formats: JPEG, PNG, BMP, GIF (first frame only), TIFF (first page only), ICO.
// Not supported: WebP, HEIC/HEIF, AVIF, JPEG 2000, animated WebP/APNG, and other raw image formats (e.g., CR2, NEF).
using var ms = new MemoryStream(coverBytes);
try

View File

@@ -27,7 +27,7 @@ using System.Windows.Threading;
namespace QuickLook;
internal static class PipeMessages
public static class PipeMessages
{
public const string RunAndClose = "QuickLook.App.PipeMessages.RunAndClose";
public const string Switch = "QuickLook.App.PipeMessages.Switch";
@@ -38,7 +38,7 @@ internal static class PipeMessages
public const string Quit = "QuickLook.App.PipeMessages.Quit";
}
internal class PipeServerManager : IDisposable
public class PipeServerManager : IDisposable
{
private static readonly string PipeName = "QuickLook.App.Pipe." + WindowsIdentity.GetCurrent().User?.Value;
private static PipeServerManager _instance;

View File

@@ -29,7 +29,7 @@ using UnblockZoneIdentifier;
namespace QuickLook;
internal class PluginManager
public class PluginManager
{
private static PluginManager _instance;

View File

@@ -28,6 +28,8 @@
<InfoPanel_File>ملف: {0}</InfoPanel_File>
<InfoPanel_Files>ملفات: {0}</InfoPanel_Files>
<InfoPanel_FolderAndFile>({0} - {1})</InfoPanel_FolderAndFile>
<InfoPanelMoreItem_CopyAsPath>نسخ كمسار</InfoPanelMoreItem_CopyAsPath>
<InfoPanelMoreItem_CopySucc>نسخ بنجاح</InfoPanelMoreItem_CopySucc>
</ar>
<hu-HU>
<UI_FontFamily>Segoe UI</UI_FontFamily>
@@ -55,6 +57,8 @@
<InfoPanel_File>{0} fájl</InfoPanel_File>
<InfoPanel_Files>{0} fájlok</InfoPanel_Files>
<InfoPanel_FolderAndFile>({0} és {1})</InfoPanel_FolderAndFile>
<InfoPanelMoreItem_CopyAsPath>Másolás elérési útként</InfoPanelMoreItem_CopyAsPath>
<InfoPanelMoreItem_CopySucc>Sikeres másolás</InfoPanelMoreItem_CopySucc>
</hu-HU>
<sk>
<UI_FontFamily>Segoe UI</UI_FontFamily>
@@ -81,6 +85,8 @@
<InfoPanel_File>{0} položka</InfoPanel_File>
<InfoPanel_Files>{0} položiek</InfoPanel_Files>
<InfoPanel_FolderAndFile>({0} a {1})</InfoPanel_FolderAndFile>
<InfoPanelMoreItem_CopyAsPath>Kopírovať ako cestu</InfoPanelMoreItem_CopyAsPath>
<InfoPanelMoreItem_CopySucc>Úspešne skopírované</InfoPanelMoreItem_CopySucc>
</sk>
<id-ID>
<UI_FontFamily>Segoe UI</UI_FontFamily>
@@ -108,6 +114,8 @@
<InfoPanel_File>{0} berkas</InfoPanel_File>
<InfoPanel_Files>{0} berkas</InfoPanel_Files>
<InfoPanel_FolderAndFile>({0} dan {1})</InfoPanel_FolderAndFile>
<InfoPanelMoreItem_CopyAsPath>Salin sebagai jalur</InfoPanelMoreItem_CopyAsPath>
<InfoPanelMoreItem_CopySucc>Berhasil disalin</InfoPanelMoreItem_CopySucc>
</id-ID>
<ko>
<UI_FontFamily>Segoe UI</UI_FontFamily>
@@ -141,6 +149,8 @@
<InfoPanel_Files>{0}개 파일</InfoPanel_Files>
<InfoPanel_FolderAndFile>({0} 및 {1})</InfoPanel_FolderAndFile>
<InfoPanel_CantPreventClosing>"닫힘 방지" 취소는 지원되지 않습니다</InfoPanel_CantPreventClosing>
<InfoPanelMoreItem_CopyAsPath>경로로 복사</InfoPanelMoreItem_CopyAsPath>
<InfoPanelMoreItem_CopySucc>성공적으로 복사됨</InfoPanelMoreItem_CopySucc>
</ko>
<ca>
<UI_FontFamily>Segoe UI</UI_FontFamily>
@@ -166,6 +176,8 @@
<InfoPanel_File>{0} fitxer</InfoPanel_File>
<InfoPanel_Files>{0} fitxers</InfoPanel_Files>
<InfoPanel_FolderAndFile>({0} i {1})</InfoPanel_FolderAndFile>
<InfoPanelMoreItem_CopyAsPath>Copia com a camí</InfoPanelMoreItem_CopyAsPath>
<InfoPanelMoreItem_CopySucc>Copiat correctament</InfoPanelMoreItem_CopySucc>
</ca>
<de>
<UI_FontFamily>Segoe UI</UI_FontFamily>
@@ -201,6 +213,8 @@
<InfoPanel_Files>{0} Dateien</InfoPanel_Files>
<InfoPanel_FolderAndFile>({0} und {1})</InfoPanel_FolderAndFile>
<InfoPanel_CantPreventClosing>Das Aufheben von "Anheften" wird nicht unterstützt.</InfoPanel_CantPreventClosing>
<InfoPanelMoreItem_CopyAsPath>Als Pfad kopieren</InfoPanelMoreItem_CopyAsPath>
<InfoPanelMoreItem_CopySucc>Erfolgreich kopiert</InfoPanelMoreItem_CopySucc>
</de>
<en>
<UI_FontFamily>Segoe UI</UI_FontFamily>
@@ -272,6 +286,8 @@
<InfoPanel_File>{0} archivo</InfoPanel_File>
<InfoPanel_Files>{0} archivos</InfoPanel_Files>
<InfoPanel_FolderAndFile>({0} y {1})</InfoPanel_FolderAndFile>
<InfoPanelMoreItem_CopyAsPath>Copiar como ruta</InfoPanelMoreItem_CopyAsPath>
<InfoPanelMoreItem_CopySucc>Copiado exitosamente</InfoPanelMoreItem_CopySucc>
</es>
<fr>
<UI_FontFamily>Segoe UI</UI_FontFamily>
@@ -302,6 +318,8 @@
<InfoPanel_File>{0} fichier</InfoPanel_File>
<InfoPanel_Files>{0} fichiers</InfoPanel_Files>
<InfoPanel_FolderAndFile>({0} et {1})</InfoPanel_FolderAndFile>
<InfoPanelMoreItem_CopyAsPath>Copier comme chemin</InfoPanelMoreItem_CopyAsPath>
<InfoPanelMoreItem_CopySucc>Copié avec succès</InfoPanelMoreItem_CopySucc>
</fr>
<it>
<UI_FontFamily>Segoe UI</UI_FontFamily>
@@ -332,6 +350,8 @@
<InfoPanel_File>{0} file</InfoPanel_File>
<InfoPanel_Files>{0} file</InfoPanel_Files>
<InfoPanel_FolderAndFile>({0} e {1})</InfoPanel_FolderAndFile>
<InfoPanelMoreItem_CopyAsPath>Copia come percorso</InfoPanelMoreItem_CopyAsPath>
<InfoPanelMoreItem_CopySucc>Copiato con successo</InfoPanelMoreItem_CopySucc>
</it>
<ja>
<UI_FontFamily>Segoe UI,Meiryo UI,MS Gothic</UI_FontFamily>
@@ -366,6 +386,8 @@
<InfoPanel_Files>{0} ファイル</InfoPanel_Files>
<InfoPanel_FolderAndFile>({0}と {1})</InfoPanel_FolderAndFile>
<InfoPanel_CantPreventClosing>「閉じるのを防ぐ」はキャンセル不可</InfoPanel_CantPreventClosing>
<InfoPanelMoreItem_CopyAsPath>パスとしてコピー</InfoPanelMoreItem_CopyAsPath>
<InfoPanelMoreItem_CopySucc>正常にコピーされました</InfoPanelMoreItem_CopySucc>
</ja>
<nb-NO>
<UI_FontFamily>Segoe UI</UI_FontFamily>
@@ -391,6 +413,8 @@
<InfoPanel_File>{0} fil</InfoPanel_File>
<InfoPanel_Files>{0} filer</InfoPanel_Files>
<InfoPanel_FolderAndFile>({0} og {1})</InfoPanel_FolderAndFile>
<InfoPanelMoreItem_CopyAsPath>Kopier som sti</InfoPanelMoreItem_CopyAsPath>
<InfoPanelMoreItem_CopySucc>Kopiert vellykket</InfoPanelMoreItem_CopySucc>
</nb-NO>
<nl-NL>
<UI_FontFamily>Segoe UI</UI_FontFamily>
@@ -416,6 +440,8 @@
<InfoPanel_File>{0} bestand</InfoPanel_File>
<InfoPanel_Files>{0} bestanden</InfoPanel_Files>
<InfoPanel_FolderAndFile>({0} en {1})</InfoPanel_FolderAndFile>
<InfoPanelMoreItem_CopyAsPath>Kopiëren als pad</InfoPanelMoreItem_CopyAsPath>
<InfoPanelMoreItem_CopySucc>Succesvol gekopieerd</InfoPanelMoreItem_CopySucc>
</nl-NL>
<pl>
<UI_FontFamily>Segoe UI</UI_FontFamily>
@@ -451,6 +477,8 @@
<InfoPanel_Files>{0} plików</InfoPanel_Files>
<InfoPanel_FolderAndFile>({0} i {1})</InfoPanel_FolderAndFile>
<InfoPanel_CantPreventClosing>Anulowanie dla funkcji blokady zamykania okna nie jest wspierane</InfoPanel_CantPreventClosing>
<InfoPanelMoreItem_CopyAsPath>Kopiuj jako ścieżkę</InfoPanelMoreItem_CopyAsPath>
<InfoPanelMoreItem_CopySucc>Skopiowano pomyślnie</InfoPanelMoreItem_CopySucc>
</pl>
<pt-BR>
<UI_FontFamily>Segoe UI</UI_FontFamily>
@@ -486,6 +514,8 @@
<InfoPanel_Files>{0} arquivos</InfoPanel_Files>
<InfoPanel_FolderAndFile>({0} e {1})</InfoPanel_FolderAndFile>
<InfoPanel_CantPreventClosing>Não é possível cancelar "Impedir fechamento"</InfoPanel_CantPreventClosing>
<InfoPanelMoreItem_CopyAsPath>Copiar como caminho</InfoPanelMoreItem_CopyAsPath>
<InfoPanelMoreItem_CopySucc>Copiado com sucesso</InfoPanelMoreItem_CopySucc>
</pt-BR>
<pt-PT>
<UI_FontFamily>Segoe UI</UI_FontFamily>
@@ -511,6 +541,8 @@
<InfoPanel_File>{0} ficheiro</InfoPanel_File>
<InfoPanel_Files>{0} ficheiros</InfoPanel_Files>
<InfoPanel_FolderAndFile>({0} e {1})</InfoPanel_FolderAndFile>
<InfoPanelMoreItem_CopyAsPath>Copiar como caminho</InfoPanelMoreItem_CopyAsPath>
<InfoPanelMoreItem_CopySucc>Copiado com sucesso</InfoPanelMoreItem_CopySucc>
</pt-PT>
<ru-RU>
<UI_FontFamily>Segoe UI</UI_FontFamily>
@@ -543,6 +575,8 @@
<InfoPanel_File>{0} файл</InfoPanel_File>
<InfoPanel_Files>{0} файла(ов)</InfoPanel_Files>
<InfoPanel_FolderAndFile>({0} и {1})</InfoPanel_FolderAndFile>
<InfoPanelMoreItem_CopyAsPath>Копировать как путь</InfoPanelMoreItem_CopyAsPath>
<InfoPanelMoreItem_CopySucc>Успешно скопировано</InfoPanelMoreItem_CopySucc>
</ru-RU>
<tr-TR>
<UI_FontFamily>Segoe UI</UI_FontFamily>
@@ -570,6 +604,8 @@
<InfoPanel_File>{0} dosya</InfoPanel_File>
<InfoPanel_Files>{0} dosya</InfoPanel_Files>
<InfoPanel_FolderAndFile>({0} ve {1})</InfoPanel_FolderAndFile>
<InfoPanelMoreItem_CopyAsPath>Yol olarak kopyala</InfoPanelMoreItem_CopyAsPath>
<InfoPanelMoreItem_CopySucc>Başarıyla kopyalandı</InfoPanelMoreItem_CopySucc>
</tr-TR>
<uk-UA>
<UI_FontFamily>Segoe UI</UI_FontFamily>
@@ -604,6 +640,8 @@
<InfoPanel_File>{0} файл</InfoPanel_File>
<InfoPanel_Files>{0} файли(ів)</InfoPanel_Files>
<InfoPanel_FolderAndFile>({0} та {1})</InfoPanel_FolderAndFile>
<InfoPanelMoreItem_CopyAsPath>Копіювати як шлях</InfoPanelMoreItem_CopyAsPath>
<InfoPanelMoreItem_CopySucc>Успішно скопійовано</InfoPanelMoreItem_CopySucc>
</uk-UA>
<vi>
<UI_FontFamily>Segoe UI</UI_FontFamily>
@@ -630,6 +668,8 @@
<InfoPanel_File>{0} tệp</InfoPanel_File>
<InfoPanel_Files>{0} tệp</InfoPanel_Files>
<InfoPanel_FolderAndFile>({0} và {1})</InfoPanel_FolderAndFile>
<InfoPanelMoreItem_CopyAsPath>Sao chép dưới dạng đường dẫn</InfoPanelMoreItem_CopyAsPath>
<InfoPanelMoreItem_CopySucc>Sao chép thành công</InfoPanelMoreItem_CopySucc>
</vi>
<zh-CN>
<UI_FontFamily>Segoe UI,Microsoft Yahei UI,Microsoft Yahei,SimSun</UI_FontFamily>
@@ -665,6 +705,8 @@
<InfoPanel_Files>{0} 个文件</InfoPanel_Files>
<InfoPanel_FolderAndFile>(含 {0}和 {1})</InfoPanel_FolderAndFile>
<InfoPanel_CantPreventClosing>不可取消“阻止关闭”哟</InfoPanel_CantPreventClosing>
<InfoPanelMoreItem_CopyAsPath>复制为路径</InfoPanelMoreItem_CopyAsPath>
<InfoPanelMoreItem_CopySucc>复制成功</InfoPanelMoreItem_CopySucc>
</zh-CN>
<zh-TW>
<UI_FontFamily>Segoe UI,Microsoft JhengHei UI,Microsoft JhengHei,MingLiU</UI_FontFamily>
@@ -700,6 +742,8 @@
<InfoPanel_Files>{0} 個檔案</InfoPanel_Files>
<InfoPanel_FolderAndFile>(包含 {0}和 {1})</InfoPanel_FolderAndFile>
<InfoPanel_CantPreventClosing>不可取消“阻止關閉”喲</InfoPanel_CantPreventClosing>
<InfoPanelMoreItem_CopyAsPath>複製為路徑</InfoPanelMoreItem_CopyAsPath>
<InfoPanelMoreItem_CopySucc>複製成功</InfoPanelMoreItem_CopySucc>
</zh-TW>
<mr>
<UI_FontFamily>Segoe UI</UI_FontFamily>

View File

@@ -22,11 +22,10 @@ using System;
using System.Diagnostics;
using System.IO;
using System.Runtime.ExceptionServices;
using System.Windows;
namespace QuickLook;
internal class ViewWindowManager : IDisposable
public class ViewWindowManager : IDisposable
{
private static ViewWindowManager _instance;
@@ -239,7 +238,7 @@ internal class ViewWindowManager : IDisposable
};
}
internal static ViewWindowManager GetInstance()
public static ViewWindowManager GetInstance()
{
return _instance ??= new ViewWindowManager();
}

View File

@@ -17,15 +17,22 @@
using QuickLook.Common.Helpers;
using QuickLook.Common.Plugin;
using QuickLook.Common.Plugin.MoreMenu;
using QuickLook.Helpers;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.ExceptionServices;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Threading;
using Wpf.Ui.Controls;
using MenuItem = System.Windows.Controls.MenuItem;
namespace QuickLook;
@@ -57,7 +64,7 @@ public partial class ViewerWindow
private void PositionWindow(Size size)
{
// if the window is now now maximized, do not move it
// If the window is now now maximized, do not move it
if (WindowState == WindowState.Maximized)
return;
@@ -70,7 +77,7 @@ public partial class ViewerWindow
private Rect ResizeAndCentreExistingWindow(Size size)
{
// align window just like in macOS ...
// Align window just like in macOS ...
//
// |10%| 80% |10%|
// |---|-----------|---|---
@@ -88,11 +95,11 @@ public partial class ViewerWindow
var limitPercentX = 0.1 * scale.Horizontal;
var limitPercentY = 0.1 * scale.Vertical;
// use absolute pixels for calculation
// Use absolute pixels for calculation
var pxSize = new Size(scale.Horizontal * size.Width, scale.Vertical * size.Height);
var pxOldRect = this.GetWindowRectInPixel();
// scale to new size, maintain centre
// Scale to new size, maintain centre
var pxNewRect = Rect.Inflate(pxOldRect,
(pxSize.Width - pxOldRect.Width) / 2,
(pxSize.Height - pxOldRect.Height) / 2);
@@ -121,7 +128,7 @@ public partial class ViewerWindow
pxNewRect.Offset(0,
Math.Max(0, desktopRect.Top - pxNewRect.Top) + Math.Min(0, desktopRect.Bottom - pxNewRect.Bottom));
// return absolute location and relative size
// Return absolute location and relative size
return new Rect(pxNewRect.Location, size);
}
@@ -135,13 +142,13 @@ public partial class ViewerWindow
desktopRect.X + (desktopRect.Width - pxSize.Width) / 2,
desktopRect.Y + (desktopRect.Height - pxSize.Height) / 2);
// return absolute location and relative size
// Return absolute location and relative size
return new Rect(pxLocation, size);
}
internal void UnloadPlugin()
{
// the focused element will not processed by GC: https://stackoverflow.com/questions/30848939/memory-leak-due-to-window-efectivevalues-retention
// The focused element will not processed by GC: https://stackoverflow.com/questions/30848939/memory-leak-due-to-window-efectivevalues-retention
FocusManager.SetFocusedElement(this, null);
Keyboard.DefaultRestoreFocusMode =
RestoreFocusMode.None; // WPF will put the focused item into a "_restoreFocus" list ... omg
@@ -180,10 +187,10 @@ public partial class ViewerWindow
ContextObject.Reset();
// assign monitor color profile
// Assign monitor color profile
ContextObject.ColorProfileName = DisplayDeviceHelper.GetMonitorColorProfileFromWindow(this);
// get window size before showing it
// Get window size before showing it
try
{
Plugin.Prepare(path, ContextObject);
@@ -194,9 +201,30 @@ public partial class ViewerWindow
return;
}
// Initial the more menu
ClearMoreMenuUnpin();
foreach (var plugin in PluginManager.GetInstance().LoadedPlugins)
{
if (plugin == Plugin)
{
if (Plugin is IMoreMenu moreMenu && moreMenu.MenuItems is not null)
{
InsertMoreMenu(moreMenu.MenuItems);
}
continue;
}
else
{
if (plugin is IMoreMenuExtended moreMenu && moreMenu.MenuItems is not null)
{
InsertMoreMenu(moreMenu.MenuItems);
}
}
}
SetOpenWithButtonAndPath();
// revert UI changes
// Revert UI changes
ContextObject.IsBusy = true;
var newHeight = ContextObject.PreferredSize.Height + BorderThickness.Top + BorderThickness.Bottom +
@@ -204,7 +232,7 @@ public partial class ViewerWindow
var newWidth = ContextObject.PreferredSize.Width + BorderThickness.Left + BorderThickness.Right;
var newSize = new Size(newWidth, newHeight);
// if use has adjusted the window size, keep it
// If use has adjusted the window size, keep it
if (_customWindowSize != Size.Empty)
newSize = _customWindowSize;
else
@@ -231,7 +259,7 @@ public partial class ViewerWindow
_autoReloadWatcher.EnableRaisingEvents = true;
}
// load plugin, do not block UI
// Load plugin, do not block UI
Dispatcher.BeginInvoke(new Action(() =>
{
try
@@ -246,12 +274,79 @@ public partial class ViewerWindow
DispatcherPriority.Input);
}
private void ClearMoreMenuUnpin()
{
var toRemove = buttonMore.ContextMenu.Items
.OfType<FrameworkElement>() // MenuItem and Separator
.Where(item => item.Tag is not "PinMenu")
.ToArray();
foreach (var item in toRemove)
{
buttonMore.ContextMenu.Items.Remove(item);
}
}
private void InsertMoreMenu(IEnumerable<IMenuItem> moreMenu)
{
int count = 0;
foreach (IMenuItem item in moreMenu)
{
if (item is null) continue;
if (!item.IsSeparator)
{
MenuItem menuItem = new()
{
Header = item.Header,
Icon = ResolveIcon(item.Icon),
Visibility = item.IsVisible ? Visibility.Visible : Visibility.Collapsed,
Command = item.Command,
};
buttonMore.ContextMenu.Items.Insert(count++, menuItem);
}
else
{
buttonMore.ContextMenu.Items.Insert(count++, new Separator());
}
}
if (moreMenu.Any())
{
buttonMore.ContextMenu.Items.Insert(count++, new Separator());
}
}
private object ResolveIcon(object icon)
{
if (icon is string glyph)
{
return new FontIcon()
{
FontFamily = (FontFamily)Application.Current.Resources["SymbolThemeFontFamily"],
Glyph = glyph,
};
}
else if (icon is UIElement)
{
return icon;
}
else
{
// Not supported yet
}
return null;
}
private void SetOpenWithButtonAndPath()
{
// share icon
// Share icon
buttonShare.Visibility = ShareHelper.IsShareSupported(_path) ? Visibility.Visible : Visibility.Collapsed;
// open icon
// Open icon
if (Directory.Exists(_path))
{
buttonOpen.ToolTip = string.Format(TranslationHelper.Get("MW_BrowseFolder"), Path.GetFileName(_path));
@@ -265,7 +360,7 @@ public partial class ViewerWindow
return;
}
// not an exe
// Not an exe
var found = FileHelper.GetAssocApplication(_path, out appFriendlyName);
if (found)
{
@@ -273,7 +368,7 @@ public partial class ViewerWindow
return;
}
// assoc not found
// Assoc not found
buttonOpen.ToolTip = string.Format(TranslationHelper.Get("MW_Open"), Path.GetFileName(_path));
}

View File

@@ -132,14 +132,15 @@
ToolTip="More">
<Button.ContextMenu>
<ContextMenu FontSize="12">
<MenuItem x:Name="moreItemCopyAsPath">
<MenuItem x:Name="moreItemCopyAsPath" Tag="PinMenu">
<MenuItem.Icon>
<ui:FontIcon FontFamily="{DynamicResource SymbolThemeFontFamily}" Glyph="{x:Static ui:FontSymbols.Copy}" />
</MenuItem.Icon>
</MenuItem>
<Separator Visibility="Collapsed" />
<Separator Tag="PinMenu" Visibility="Collapsed" />
<MenuItem x:Name="moreItemOpenSettings"
Header="Settings"
Tag="PinMenu"
Visibility="Collapsed">
<MenuItem.Icon>
<ui:FontIcon FontFamily="{DynamicResource SymbolThemeFontFamily}" Glyph="{x:Static ui:FontSymbols.Settings}" />

View File

@@ -62,7 +62,11 @@ Get it from one of the following sources:
- <kbd>Ctrl</kbd>+<kbd>Mouse Wheel</kbd> Zoom in/out (PDFs)
- <kbd>Wheel</kbd> Increase/decrease volume
## Supported file types, file manager integration, etc.
## Supported file formats
See the [Supported formats](SUPPORTED_FORMATS.md)
## Supported file manager integration, etc.
See the [Wiki page](https://github.com/QL-Win/QuickLook/wiki)

View File

@@ -1,11 +1,135 @@
## Supported formats in QuickLook
## Supported Formats in QuickLook
Update not completed yet...
### Text files
- `.txt` (Plain text file)
- `.rtf` (Rich Text Format)
- Most other plain text files
- `.log` (Log file)
- `.ini` (Initialization/config file)
- `.json` (JavaScript Object Notation)
- `.xml` (Extensible Markup Language)
- `.yaml`, `.yml` (YAML Ain't Markup Language)
- `.md`, `.markdown`, `.mdx`, `.mmd`, `.mkd`, `.mdwn`, `.mdown`, `.mdc`, `.qmd`, `.rmd`, `.rmarkdown`, `.apib`, `.mdtxt`, `.mdtext` (Markdown and variants)
- `.csv` (Comma-separated values)
- `.tsv` (Tab-separated values)
- `.bat`, `.cmd` (Batch script)
- `.ps1` (PowerShell script)
- `.sh` (Shell script)
- `.c`, `.cpp`, `.h`, `.hpp` (C/C++ source/header)
- `.cs` (C# source)
- `.java` (Java source)
- `.py` (Python source)
- `.js` (JavaScript source)
- `.ts`, `.tsx`, `.uts` (TypeScript source)
- `.go` (Go source)
- `.php` (PHP source)
- `.rb` (Ruby source)
- `.swift` (Swift source)
- `.scala` (Scala source)
- `.kotlin` (Kotlin source)
- `.lua` (Lua source)
- `.sql` (SQL script)
- `.css` (Cascading Style Sheets)
- `.html`, `.htm` (HTML file)
- `.xshd` (Highlighting definition)
- `.properties` (Java properties/config)
- `.diff`, `.patch` (Diff/Patch file)
- `.sub`, `.srt` (Subtitle file)
- `.conf`, `.config` (Configuration file)
- `.env` (Environment config)
- `.makefile`, `.mk` (Makefile)
- `.gitignore`, `.gitattributes` (Git config)
- `.registry` (Windows registry file)
- `.resource` (Resource file)
- `.hosts` (Hosts file)
- `.boo` (Boo script)
- `.ada` (Ada source)
- `.antlr` (ANTLR grammar)
- `.assembly` (Assembly source)
- `.autohotkey` (AutoHotkey script)
- `.ceylon` (Ceylon source)
- `.chuck` (ChucK script)
- `.clojure` (Clojure source)
- `.cmake` (CMake config)
- `.cocoa` (Cocoa source)
- `.coffeescript` (CoffeeScript source)
- `.cool` (Cool source)
- `.d` (D source)
- `.dart` (Dart source)
- `.delphi` (Delphi source)
- `.eiffel` (Eiffel source)
- `.elixir` (Elixir source)
- `.env` (Environment config)
- `.erlang` (Erlang source)
- `.fsharp` (F# source)
- `.falcon` (Falcon script)
- `.fantom` (Fantom source)
- `.fortran` (Fortran source)
- `.gitattributes` (Git attributes)
- `.gitignore` (Git ignore)
- `.goovy` (Goovy source)
- `.gui4cli` (Gui4Cli script)
- `.haskell` (Haskell source)
- `.haxe` (Haxe source)
- `.hlsl` (HLSL shader)
- `.hosts` (Hosts file)
- `.icon` (Icon source)
- `.ilyc` (ILYC source)
- `.ini` (INI config)
- `.io` (Io source)
- `.java` (Java source)
- `.justbasic` (Just BASIC source)
- `.kixtart` (KiXtart script)
- `.kotlin` (Kotlin source)
- `.lean` (Lean source)
- `.lisp` (Lisp source)
- `.log` (Log file)
- `.lua` (Lua source)
- `.lyric` (Lyric file)
- `.makefile`, `.mk` (Makefile)
- `.nemerle` (Nemerle source)
- `.nim` (Nim source)
- `.nsis` (NSIS script)
- `.objective-c` (Objective-C source)
- `.ocaml` (OCaml source)
- `.parasail` (ParaSail source)
- `.pascal` (Pascal source)
- `.php` (PHP source)
- `.pike` (Pike source)
- `.prolog` (Prolog source)
- `.protobuf` (Protocol Buffers)
- `.purescript` (PureScript source)
- `.qml` (QML source)
- `.r` (R script)
- `.restructuredtext` (reStructuredText)
- `.rexx` (Rexx script)
- `.ruby` (Ruby source)
- `.rust` (Rust source)
- `.scala` (Scala source)
- `.scheme` (Scheme source)
- `.shellscript`, `.sh` (Shell script)
- `.solidity` (Solidity source)
- `.spike` (Spike source)
- `.sqf` (SQF script)
- `.subripsubtitle`, `.sub`, `.srt` (SubRip Subtitle)
- `.swift` (Swift source)
- `.tcl` (TCL script)
- `.thrift` (Thrift source)
- `.vala` (Vala source)
- `.vbnet` (VB.NET source)
- `.vbscript` (VBScript)
- `.verilog` (Verilog source)
- `.vhdl` (VHDL source)
- `.visualsolution` (VisualSolution source)
- `.volt` (Volt source)
- `.vue` (Vue component)
- `.x10` (X10 source)
- `.xc` (XC source)
- `.xml` (Extensible Markup Language)
- `.xtend` (Xtend source)
- Most other plain text and script formats
### Image files
- `.apng` (Animated PNG)
@@ -37,6 +161,7 @@
- `.jxl` (JPEG XL)
- `.jxr` (JPEG XR)
- `.k25`, `.kdc` (Kodak RAW image)
- `.lottie` (Lottie animation)
- `.mdc` (MagicDraw UML)
- `.mef` (Mamiya RAW image)
- `.mos` (Leaf RAW image)
@@ -60,7 +185,9 @@
- `.rw2`, `.rwl`, `.rwz` (Panasonic/Leica RAW image)
- `.sr2`, `.srf`, `.srw` (Sony RAW image)
- `.svg`, `.svgz` (Scalable Vector Graphics)
- `.svga` (SVGA animation)
- `.tga` (Truevision TGA)
- `.tgs` (Telegram sticker, Lottie animation)
- `.tif`, `.tiff` (Tagged Image File Format)
- `.wdp` (Windows Media Photo)
- `.webp` (WebP image)
@@ -80,7 +207,7 @@
- `.gz` (Gzip archive)
- `.jar` (Java archive)
- `.lz` (Lzip archive)
- `.nupkg` (NuGet package)
- `.nupkg`, `.snupkg` (NuGet package)
- `.rar` (RAR archive)
- `.tar`, `.tgz` (TAR archive)
- `.vsix` (Visual Studio extension)