Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions docs/ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,25 @@ multi-frame pictures refused, the EXIF thumbnail dropped), one history entry for
- `Controls/CropMath` holds the arithmetic (ratios and their portrait forms, nudging by whole pixels, the frame in
pixels, where the size chip goes, where the dial opens) and is unit tested.

## Spreadsheet print studio

The `tool-sheet-studio` tool opens an independent `Views/SpreadsheetPrintStudioWindow` for each dropped XLSX workbook
instead of starting a normal conversion job. `SpreadsheetPrintStudioViewModel` owns an ordered, non-destructive print plan: each visible
sheet starts as one region and the user can add more regions, change paper, orientation, scale, margins, page order,
hidden rows and manual breaks, then see the PDF that those settings will produce.

- `SpreadsheetPrintInspector` reads workbook metadata and streams the large worksheet data with `XmlReader`; opening
a large workbook neither builds nor retains an `XDocument` for every sheet.
- `SpreadsheetPrintPackage` makes a disposable XLSX under `JobQueue.DefaultWorkRoot`. It keeps every worksheet and
named range so cross-sheet formulas remain valid, hides the sheets not being rendered, and changes only the chosen
sheet's print settings. A new print area is written only after the user explicitly changes or accepts the range.
- `SpreadsheetPrintService` runs LibreOffice once for each region. Preview and export use the same disposable-workbook
path; export then joins the region PDFs in the chosen order with PDFsharp. The ordinary XLSX → PDF donut conversion
can still differ because route planning may select Filee's built-in spreadsheet reader instead of LibreOffice.
- `PdfPreviewDocument` caches a PDF's bytes and page geometry. The studio asks PDFium/PDFtoImage for small thumbnails
and only one large selected page, all decoded away from the UI thread; exporting never performs preview rendering.
Cancellation closes LibreOffice and the temporary job folder is removed on success, error or window close.

## Settings and data

`UserDataStore` owns `settings.json`, `presets.json`, `profiles.json` and `history.json`
Expand Down
9 changes: 8 additions & 1 deletion docs/ENGINES.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Filee chooses engines automatically. Settings → *Engines* shows their status,
| Windows Imaging Component | part of Windows (Windows only) | **JPEG XR** (JXR, WDP, HDP; HDR screenshots of Windows) → the images ImageMagick writes, and PDF, ICNS, HEIC and SVG through PNG; HDR tone-mapped to SDR |
| Vector graphics | built in (Svg.Skia, SkiaSharp, ACadSharp) | **SVG/SVGZ → PDF (vector) and images**, SVG ↔ SVGZ, **SVG → DXF** (→ DWG with the CAD engine), **raster images → SVG (tracing)**, PDF-compatible AI → PDF, **HP-GL / HP-GL/2 plot files (PLT) → SVG**, PDF and images (pen moves, packed PE polylines, arcs and filled polygons; text labels are not drawn), **Tajima DST embroidery → SVG** (stitches as lines, a palette colour per thread; → PNG, JPG, PDF from there) |
| ICNS | built in | images → ICNS (16–1024 px), ICNS → images |
| PDFsharp | built in (library) | images → PDF, merge, split, page ranges, **compression** (smaller PDFs, see below), PDFs without their metadata |
| PDFsharp | built in (library) | images → PDF, merge, split, page ranges, spreadsheet print-studio assembly, **compression** (smaller PDFs, see below), PDFs without their metadata |
| PDFium | built in (library) | PDF → images (multi-page TIFF/GIF supported) |
| Unhwp | built in (library) | HWP/HWPX → TXT, Markdown, HTML (pictures in a `<name>_files` folder next to the Markdown, embedded in the HTML) |
| Text & Markdown (Markdig) | built in (library) | **Markdown → HTML, TXT**; **TXT, LOG, PY, PAC, BAT, COMMAND, LUA, CSS, PS1 → UTF-8 TXT**, preserving source text without running scripts (and → PDF / DOCX through the HWPX writer, rhwp or LibreOffice) |
Expand Down Expand Up @@ -426,6 +426,13 @@ the text the spreadsheet shows, the value behind it and its Excel number format.
- Not converted: formulas (their cached results are kept), charts, pictures, comments, conditional formatting,
data validation, print areas and page breaks.

The XLSX donut also offers **PDF + Edit** (`tool-sheet-studio`). Unlike an ordinary routed XLSX → PDF conversion,
this interactive tool always requires LibreOffice regardless of engine priority: it preserves the original workbook,
makes one disposable copy per selected sheet region, applies that region's print settings, and asks LibreOffice to
render it. PDFsharp combines the resulting PDFs. The live preview follows this exact studio export path and uses
PDFium/PDFtoImage for lazy thumbnails and the selected large page; the ordinary donut's PDF can differ because its
built-in XLSX route reads the workbook into Filee's document model.

## Fonts

Fonts are converted in-process (`Filee.Engines/Fonts`); zlib and Brotli come with .NET. The input format is
Expand Down
40 changes: 40 additions & 0 deletions src/Filee.App/Assets/i18n/ar.json
Original file line number Diff line number Diff line change
Expand Up @@ -933,6 +933,46 @@
"watch.status_starting": "جارٍ البدء…",
"watch.status_error": "تعذّرت مراقبة هذا المجلد: {0}",
"watch.cli_hint": "متاح أيضًا من سطر الأوامر: filee watch <folder> --to <format>",
"preset.sheet_studio": "PDF + تحرير",
"sheet_studio.title": "استوديو طباعة جداول البيانات",
"sheet_studio.sheets": "الأوراق وترتيب الإخراج",
"sheet_studio.page_setup": "إعداد الصفحة",
"sheet_studio.print_area": "نطاق الطباعة",
"sheet_studio.use_content": "استخدام المحتوى",
"sheet_studio.paper": "الورق",
"sheet_studio.orientation": "الاتجاه",
"sheet_studio.scaling": "التحجيم",
"sheet_studio.percent": "النسبة المئوية",
"sheet_studio.pages_wide": "عدد الصفحات عرضًا",
"sheet_studio.pages_tall": "عدد الصفحات طولًا (0 = تلقائي)",
"sheet_studio.margins": "الهوامش",
"sheet_studio.margin_top": "أعلى",
"sheet_studio.margin_bottom": "أسفل",
"sheet_studio.margin_left": "يسار",
"sheet_studio.margin_right": "يمين",
"sheet_studio.page_order": "ترتيب الصفحات",
"sheet_studio.include_hidden": "تضمين الصفوف والأعمدة المخفية",
"sheet_studio.keep_breaks": "الاحتفاظ بفواصل الصفحات اليدوية",
"sheet_studio.reset_sheet": "إعادة ضبط هذه الورقة",
"sheet_studio.rendering": "جارٍ إنشاء معاينة PDF مطابقة…",
"sheet_studio.export_pdf": "تصدير PDF",
"sheet_studio.invalid_range": "أدخل نطاقًا صالحًا، مثل A1:S52.",
"sheet_studio.exporting": "جارٍ إنشاء الأوراق ودمجها…",
"sheet_studio.exported": "تم تصدير {0}",
"sheet_studio.page_count": "{0} صفحة · المعاينة مطابقة للتصدير",
"sheet_studio.from_workbook": "من المصنف",
"sheet_studio.portrait": "عمودي",
"sheet_studio.landscape": "أفقي",
"sheet_studio.fit_pages": "ملاءمة للصفحات",
"sheet_studio.exact_scale": "مقياس دقيق",
"sheet_studio.down_over": "إلى الأسفل ثم إلى اليمين",
"sheet_studio.over_down": "إلى اليمين ثم إلى الأسفل",
"sheet_studio.warning_scale": "يطلب المصنف مقياسًا قدره {0}% فقط، مما يجعل الجدول صغيرًا جدًا غالبًا.",
"sheet_studio.warning_wide": "المحتوى عريض جدًا ولا يملك نطاق طباعة. استخدم المحتوى ثم اختر عدد الصفحات عرضًا.",
"sheet_studio.apply_fix": "تطبيق التخطيط المقترح",
"sheet_studio.add_region": "+ إضافة نطاق آخر",
"sheet_studio.region_name": "{0} · النطاق {1}",

"whats_new.title": "الجديد في Filee {0}",
"whats_new.previous": "السابق",
"whats_new.next": "التالي",
Expand Down
40 changes: 40 additions & 0 deletions src/Filee.App/Assets/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -954,6 +954,46 @@
"watch.status_error": "Can't watch this folder: {0}",
"watch.cli_hint": "Also on the command line: filee watch <folder> --to <format>",

"preset.sheet_studio": "PDF + Edit",
"sheet_studio.title": "Spreadsheet Print Studio",
"sheet_studio.sheets": "Sheets and output order",
"sheet_studio.page_setup": "Page setup",
"sheet_studio.print_area": "Print area",
"sheet_studio.use_content": "Use content",
"sheet_studio.paper": "Paper",
"sheet_studio.orientation": "Orientation",
"sheet_studio.scaling": "Scaling",
"sheet_studio.percent": "Percent",
"sheet_studio.pages_wide": "Pages wide",
"sheet_studio.pages_tall": "Pages tall (0 = auto)",
"sheet_studio.margins": "Margins (top, bottom, left, right)",
"sheet_studio.margin_top": "Top",
"sheet_studio.margin_bottom": "Bottom",
"sheet_studio.margin_left": "Left",
"sheet_studio.margin_right": "Right",
"sheet_studio.page_order": "Page order",
"sheet_studio.include_hidden": "Include hidden rows and columns",
"sheet_studio.keep_breaks": "Keep manual page breaks",
"sheet_studio.reset_sheet": "Reset this sheet",
"sheet_studio.rendering": "Rendering the exact PDF preview…",
"sheet_studio.export_pdf": "Export PDF",
"sheet_studio.invalid_range": "Enter a valid range, for example A1:S52.",
"sheet_studio.exporting": "Rendering and combining sheets…",
"sheet_studio.exported": "Exported {0}",
"sheet_studio.page_count": "{0} page(s) · preview matches export",
"sheet_studio.from_workbook": "From workbook",
"sheet_studio.portrait": "Portrait",
"sheet_studio.landscape": "Landscape",
"sheet_studio.fit_pages": "Fit to pages",
"sheet_studio.exact_scale": "Exact scale",
"sheet_studio.down_over": "Down, then over",
"sheet_studio.over_down": "Over, then down",
"sheet_studio.warning_scale": "The workbook requests only {0}% scale. This often makes the table tiny.",
"sheet_studio.warning_wide": "Very wide content has no print area. Use Content, then choose how many pages wide it should be.",
"sheet_studio.apply_fix": "Apply suggested layout",
"sheet_studio.add_region": "+ Add another region",
"sheet_studio.region_name": "{0} · region {1}",

"whats_new.title": "What's new in Filee {0}",
"whats_new.previous": "Previous",
"whats_new.next": "Next",
Expand Down
40 changes: 40 additions & 0 deletions src/Filee.App/Assets/i18n/es.json
Original file line number Diff line number Diff line change
Expand Up @@ -934,6 +934,46 @@
"watch.status_error": "No se puede supervisar esta carpeta: {0}",
"watch.cli_hint": "También en la línea de comandos: filee watch <carpeta> --to <formato>",

"preset.sheet_studio": "PDF + Editar",
"sheet_studio.title": "Estudio de impresión de hojas de cálculo",
"sheet_studio.sheets": "Hojas y orden de salida",
"sheet_studio.page_setup": "Configuración de página",
"sheet_studio.print_area": "Área de impresión",
"sheet_studio.use_content": "Usar contenido",
"sheet_studio.paper": "Papel",
"sheet_studio.orientation": "Orientación",
"sheet_studio.scaling": "Escala",
"sheet_studio.percent": "Porcentaje",
"sheet_studio.pages_wide": "Páginas de ancho",
"sheet_studio.pages_tall": "Páginas de alto (0 = automático)",
"sheet_studio.margins": "Márgenes",
"sheet_studio.margin_top": "Superior",
"sheet_studio.margin_bottom": "Inferior",
"sheet_studio.margin_left": "Izquierdo",
"sheet_studio.margin_right": "Derecho",
"sheet_studio.page_order": "Orden de páginas",
"sheet_studio.include_hidden": "Incluir filas y columnas ocultas",
"sheet_studio.keep_breaks": "Conservar saltos de página manuales",
"sheet_studio.reset_sheet": "Restablecer esta hoja",
"sheet_studio.rendering": "Generando la vista previa exacta del PDF…",
"sheet_studio.export_pdf": "Exportar PDF",
"sheet_studio.invalid_range": "Introduce un rango válido, por ejemplo A1:S52.",
"sheet_studio.exporting": "Generando y combinando hojas…",
"sheet_studio.exported": "Exportado: {0}",
"sheet_studio.page_count": "{0} página(s) · la vista previa coincide con la exportación",
"sheet_studio.from_workbook": "Del libro",
"sheet_studio.portrait": "Vertical",
"sheet_studio.landscape": "Horizontal",
"sheet_studio.fit_pages": "Ajustar a páginas",
"sheet_studio.exact_scale": "Escala exacta",
"sheet_studio.down_over": "Abajo y luego a la derecha",
"sheet_studio.over_down": "A la derecha y luego abajo",
"sheet_studio.warning_scale": "El libro solicita solo un {0}% de escala. Esto suele hacer que la tabla sea diminuta.",
"sheet_studio.warning_wide": "El contenido es muy ancho y no tiene área de impresión. Usa el contenido y elige cuántas páginas de ancho debe ocupar.",
"sheet_studio.apply_fix": "Aplicar diseño sugerido",
"sheet_studio.add_region": "+ Añadir otra área",
"sheet_studio.region_name": "{0} · área {1}",

"whats_new.title": "Novedades de Filee {0}",
"whats_new.previous": "Anterior",
"whats_new.next": "Siguiente",
Expand Down
40 changes: 40 additions & 0 deletions src/Filee.App/Assets/i18n/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -954,6 +954,46 @@
"watch.status_error": "Impossible de surveiller ce dossier : {0}",
"watch.cli_hint": "Aussi en ligne de commande : filee watch <folder> --to <format>",

"preset.sheet_studio": "PDF + Modifier",
"sheet_studio.title": "Atelier d’impression des feuilles de calcul",
"sheet_studio.sheets": "Feuilles et ordre de sortie",
"sheet_studio.page_setup": "Mise en page",
"sheet_studio.print_area": "Zone d’impression",
"sheet_studio.use_content": "Utiliser le contenu",
"sheet_studio.paper": "Papier",
"sheet_studio.orientation": "Orientation",
"sheet_studio.scaling": "Échelle",
"sheet_studio.percent": "Pourcentage",
"sheet_studio.pages_wide": "Pages en largeur",
"sheet_studio.pages_tall": "Pages en hauteur (0 = auto)",
"sheet_studio.margins": "Marges",
"sheet_studio.margin_top": "Haut",
"sheet_studio.margin_bottom": "Bas",
"sheet_studio.margin_left": "Gauche",
"sheet_studio.margin_right": "Droite",
"sheet_studio.page_order": "Ordre des pages",
"sheet_studio.include_hidden": "Inclure les lignes et colonnes masquées",
"sheet_studio.keep_breaks": "Conserver les sauts de page manuels",
"sheet_studio.reset_sheet": "Réinitialiser cette feuille",
"sheet_studio.rendering": "Création de l’aperçu PDF exact…",
"sheet_studio.export_pdf": "Exporter le PDF",
"sheet_studio.invalid_range": "Saisissez une plage valide, par exemple A1:S52.",
"sheet_studio.exporting": "Création et assemblage des feuilles…",
"sheet_studio.exported": "Exporté : {0}",
"sheet_studio.page_count": "{0} page(s) · l’aperçu correspond à l’export",
"sheet_studio.from_workbook": "Selon le classeur",
"sheet_studio.portrait": "Portrait",
"sheet_studio.landscape": "Paysage",
"sheet_studio.fit_pages": "Ajuster aux pages",
"sheet_studio.exact_scale": "Échelle exacte",
"sheet_studio.down_over": "Vers le bas, puis à droite",
"sheet_studio.over_down": "À droite, puis vers le bas",
"sheet_studio.warning_scale": "Le classeur demande une échelle de seulement {0} %. Le tableau devient souvent minuscule.",
"sheet_studio.warning_wide": "Le contenu est très large et n’a pas de zone d’impression. Utilisez le contenu, puis choisissez le nombre de pages en largeur.",
"sheet_studio.apply_fix": "Appliquer la mise en page suggérée",
"sheet_studio.add_region": "+ Ajouter une autre zone",
"sheet_studio.region_name": "{0} · zone {1}",

"whats_new.title": "Nouveautés de Filee {0}",
"whats_new.previous": "Précédent",
"whats_new.next": "Suivant",
Expand Down
40 changes: 40 additions & 0 deletions src/Filee.App/Assets/i18n/hi.json
Original file line number Diff line number Diff line change
Expand Up @@ -934,6 +934,46 @@
"watch.status_error": "इस फ़ोल्डर को नहीं देखा जा सकता: {0}",
"watch.cli_hint": "कमांड लाइन पर भी: filee watch <folder> --to <format>",

"preset.sheet_studio": "PDF + संपादित करें",
"sheet_studio.title": "स्प्रेडशीट प्रिंट स्टूडियो",
"sheet_studio.sheets": "शीट और आउटपुट क्रम",
"sheet_studio.page_setup": "पेज सेटअप",
"sheet_studio.print_area": "प्रिंट क्षेत्र",
"sheet_studio.use_content": "सामग्री का उपयोग करें",
"sheet_studio.paper": "काग़ज़",
"sheet_studio.orientation": "दिशा",
"sheet_studio.scaling": "स्केलिंग",
"sheet_studio.percent": "प्रतिशत",
"sheet_studio.pages_wide": "चौड़ाई में पेज",
"sheet_studio.pages_tall": "ऊँचाई में पेज (0 = स्वतः)",
"sheet_studio.margins": "मार्जिन",
"sheet_studio.margin_top": "ऊपर",
"sheet_studio.margin_bottom": "नीचे",
"sheet_studio.margin_left": "बायाँ",
"sheet_studio.margin_right": "दायाँ",
"sheet_studio.page_order": "पेज क्रम",
"sheet_studio.include_hidden": "छिपी पंक्तियाँ और कॉलम शामिल करें",
"sheet_studio.keep_breaks": "मैन्युअल पेज ब्रेक रखें",
"sheet_studio.reset_sheet": "यह शीट रीसेट करें",
"sheet_studio.rendering": "सटीक PDF पूर्वावलोकन बनाया जा रहा है…",
"sheet_studio.export_pdf": "PDF निर्यात करें",
"sheet_studio.invalid_range": "मान्य क्षेत्र दर्ज करें, जैसे A1:S52।",
"sheet_studio.exporting": "शीट बनाकर जोड़ी जा रही हैं…",
"sheet_studio.exported": "{0} निर्यात किया गया",
"sheet_studio.page_count": "{0} पेज · पूर्वावलोकन निर्यात से मेल खाता है",
"sheet_studio.from_workbook": "वर्कबुक से",
"sheet_studio.portrait": "पोर्ट्रेट",
"sheet_studio.landscape": "लैंडस्केप",
"sheet_studio.fit_pages": "पेजों में फ़िट करें",
"sheet_studio.exact_scale": "सटीक स्केल",
"sheet_studio.down_over": "नीचे, फिर दाएँ",
"sheet_studio.over_down": "दाएँ, फिर नीचे",
"sheet_studio.warning_scale": "वर्कबुक केवल {0}% स्केल माँगती है। इससे तालिका अक्सर बहुत छोटी हो जाती है।",
"sheet_studio.warning_wide": "बहुत चौड़ी सामग्री का कोई प्रिंट क्षेत्र नहीं है। सामग्री चुनें और चौड़ाई में पेजों की संख्या तय करें।",
"sheet_studio.apply_fix": "सुझाया गया लेआउट लागू करें",
"sheet_studio.add_region": "+ दूसरा क्षेत्र जोड़ें",
"sheet_studio.region_name": "{0} · क्षेत्र {1}",

"whats_new.title": "Filee {0} में नया क्या है",
"whats_new.previous": "पिछला",
"whats_new.next": "अगला",
Expand Down
Loading
Loading