# ZPreview

ZPreview is een .NET 10 WinForms-applicatie voor Windows die een preview toont
van het bestand dat momenteel geselecteerd is in ZTreeWin.

De applicatie gebruikt `ZaapZTreeState` om de huidige toestand van ZTreeWin te
volgen en om events te ontvangen bij bestandswissels, `OnHold`, quit, en
Ctrl+Shift-sneltoetsen.

## Projecten

```text
ZAAP.net/
  ZPreview/                  WinForms-applicatie
  ZPreview.Abstractions/     Interfaces en basisklassen voor preview handlers
  ZPreview.PreviewHandlers/  Ingebouwde preview handlers
  ZPreview.SQLitePreview/    SQLite preview handler in eigen project
  ZPreview.Tests/            xUnit-tests
```

## Waarom WinForms

WinForms is hier gekozen vanwege:

- directe HWND/COM-interop voor Windows Preview Handlers
- consistentie met de bestaande ZRelay-applicatie
- eenvoudig pluginmodel waarbij handlers gewoon een `Control` retourneren

## Architectuur

De hoofdapp bestaat uit:

- `MainForm`
- `ZTreeMonitorController`
- `PreviewHandlerCatalog`
- `PreviewSettingsService`
- `WindowPositionManager`

De event-flow is:

1. `ZaapZTreeState` detecteert een wijziging in ZTreeWin.
2. `ZTreeMonitorController` vertaalt dat naar app-events.
3. `MainForm` bepaalt welke handler gebruikt moet worden.
4. De actieve preview-control wordt vervangen.

## Preview Handler Model

Handlers implementeren `IPreviewHandler` uit `ZPreview.Abstractions`.

Belangrijke contracten:

- `IPreviewHandler`
- `IPreviewHandlerConfig`
- `IPreviewHandlerConfig<TConfig>`
- `IEncodingAwarePreview`
- `IFileResourcePreview`
- `IPreviewCommandHandler`
- `IPreviewStatusSource`

Handlers worden ontdekt via assembly scanning:

- ingebouwde handlers uit `ZPreview.PreviewHandlers`
- externe handlers uit `plugins/*.dll`

Plugin-loadfouten worden vastgelegd in `PluginLoadResult`.

## Ingebouwde Preview Handlers

### Tekst

- id: `builtin.text`
- encoding-keuze via toolbar
- zoekfunctie via `Ctrl+F` en `F3`
- het zoekblok is compacter gemaakt; `Next` is nu ongeveer even hoog als het zoekvak
- handlerconfiguratie voor fallback-encoding en word-wrap
- grote bestanden worden asynchroon en begrensd als preview geladen, zodat de UI bruikbaar blijft
- doorgestuurde ZTreeWin-navigatie (`pijltjes`, `PgUp`/`PgDn`, `Home`/`End`) scrollt de tekstpreview direct

### Zip-archief

- id: `builtin.zip`
- displaynaam: `Archive`
- abstraheert ZIP-, TAR- en GZip-bronnen achter dezelfde archive-preview UI
- detecteert ZIP-containers op PK-file-signature in plaats van alleen op extensie
- detecteert ook `.tar` en GZip-bestanden (`.gz`, `.gzip`, `.tgz`, `.tar.gz`)
- ondersteunt daardoor ook archieven met verkeerd benoemde of ontbrekende extensies, zolang de signature of TAR-header overeenkomt
- listviews auto-fitten nu kolommen op inhoud of header, afhankelijk van wat breder is
- klikken op een kolomheader sorteert op de onderliggende naam-, grootte-, compressie- of datumwaarden; nogmaals klikken draait de sorteerrichting om
- treeview wordt volledig uitgeklapt bij openen
- rechts van de lijst/tree staat nu een preview-paneel dat geselecteerde archiefentries via de built-in preview handlers toont
- geneste archieven kunnen daardoor ook weer via `builtin.zip` in het rechter preview-paneel geopend worden, bijvoorbeeld een `.zip` in een `.zip`
- bij wisselen tussen `List` en `Tree` blijft hetzelfde archiefbestand geselecteerd zonder de rechter preview opnieuw te laden
- de splitter tussen lijst en preview, en in de tree-tab ook die tussen tree en bestandenlijst, onthouden hun relatieve positie
- in het preview-paneel kun je de ingebouwde handler nu ook handmatig kiezen; `(autodetect)` kiest automatisch en synchroniseert daarna de werkelijk gebruikte handler in de lijst
- Windows preview handlers worden in deze ingebedde archive-previewkeuze bewust niet aangeboden; built-in handlers, inclusief `builtin.zip`, wel

### Hex

- id: `builtin.hex`
- fallback-handler voor elk bestaand bestand
- configureerbaar lettertype, bytes per regel en ASCII-modus
- de inspector toont bovenaan altijd de lengte van de huidige selectie
- het configuratiescherm houdt de inspector-opties nu in een apart scrollbaar paneel, zodat geen instellingen meer over elkaar heen vallen
- huidige implementatie toont pragmatisch maximaal de eerste 256 KiB
- `Home` en `End` springen naar begin en einde van de preview
- navigatie met pijltjes, `PgUp`/`PgDn`, `Home`/`End`; `Shift` + pijltjes breidt selectie direct uit vanaf de huidige byte

### Afbeelding

- id: `builtin.image`
- fit-to-window als standaard
- zoom met `Ctrl+scroll`
- rotatie met `R` en `L`
- reset met `Ctrl+0`

### Windows Preview Handler Host

- id: `builtin.shell`
- zoekt COM preview handlers via de standaard `shellex`-registratie
- host preview handlers via eigen COM-interoplaag
- initialiseert handlers stream-first, met fallback naar file of shell item
- concrete beschikbare Windows Preview Handlers worden als afzonderlijke keuzes in de handlerlijst getoond
- het configuratiescherm toont in `Default Order` daarnaast ook een algemene `Windows Preview Handler (registered)`-placeholder, die bij runtime wordt vervangen door de daadwerkelijk geregistreerde handler voor het huidige bestand
- initialiseert de COM preview pas nadat de host-control een bruikbare client size heeft, en stuurt daarna resize-updates door

### SQLite

- id: `builtin.sqlite`
- staat in een apart project (`ZPreview.SQLitePreview`) met eigen dependency op `Microsoft.Data.Sqlite`
- toont links objecten uit `sqlite_master` (alle kolommen behalve `sql`)
- toont rechts de SQL-definitie van het geselecteerde object
- heeft een query-tab met SQL-editor, run/stop-knop en resultaatgrid
- query-executie is asynchroon met annuleerbare run
- resultaatweergave gebruikt een virtual-mode grid voor grotere datasets
- dubbelklik op een cel opent een detailvenster (tekst of hex voor BLOB)
- contextmenu op resultaatgrid: Select All, Copy, Export As CSV
- configureerbaar lettertype voor editor en grid, plus standaard query-template
- het query-template-vak in de settings volgt direct het gekozen editor-lettertype

## Configuratie

Configuratie wordt opgeslagen in:

```text
%APPDATA%\Zaap\ZPreview\settings.json
```

Daarin staan onder meer:

- `defaultHandlerOrder`
- `extensionOverrides`
- `handlerConfig`
- `windowPositions`

Runtime-fouten en exceptions worden ook gelogd naar `zpreview.log` in dezelfde directory als `settings.json`.

Het configuratiescherm bevat:

- standaard handlervolgorde
- `Default Order` ondersteunt nu multiselect, zodat meerdere handlers tegelijk omhoog of omlaag verplaatst kunnen worden en hun mode in één keer aangepast kan worden
- per-extensie overrides slaan nu alleen expliciete afwijkingen op; de rest erft door uit de standaardvolgorde
- de lijsten in `Per Extension` ondersteunen nu ook multiselect voor het verwijderen van meerdere extensies of meerdere handler-overrides tegelijk
- handler-specifieke instellingenpanelen
- geen apart venstericoon meer in de titelbalk, zodat het niet afwijkt van de knop-icoonkeuze
- toolstripknoppen voor `Use First For Extension` en `Configuration` hebben nu een eigen icoon
- de `Freeze`-knop heeft nu ook een eigen sneeuwvlok-icoon

## Sneltoetsen

Globale sneltoetsen vanuit ZTreeWin en lokale sneltoetsen in het previewvenster:

- `Ctrl+Shift+M` minimaliseren/herstellen
- `Ctrl+Shift+F4` venster sluiten
- `Ctrl+Shift+F` preview bevriezen/ontdooien
- `Ctrl+Shift+H` volgende handler, `Ctrl+Shift+Alt+H` vorige handler
- `Ctrl+Shift+1` t/m `Ctrl+Shift+9` selecteren handlerpositie 1..9, `Ctrl+Shift+0` triggert autodetectie

`Ctrl+Shift+M` herstelt een eerder gemaximaliseerd venster nu ook weer als gemaximaliseerd.

Handler-specifieke sneltoetsen:

- `Ctrl+F` tekst zoeken
- `F3` volgende teksttreffer
- `F5` / `F9` SQLite query uitvoeren/stoppen
- `Ctrl+0` afbeelding resetten
- `R` / `L` afbeelding roteren
- `builtin.hex`: pijltjes, `PgUp`/`PgDn`, `Home`/`End`; via ZTreeWin worden `Ctrl+Shift`-varianten doorgestuurd, en `Ctrl+Shift+Alt` + pijltjes wordt vertaald naar selectie met `Shift` + pijltjes
- `builtin.text`: via ZTreeWin scrollen `Ctrl+Shift` + pijltjes, `PgUp`/`PgDn`, `Home` en `End` de tekstpreview

## Vensterpositie

De vensterpositie wordt onthouden per monitorconfiguratie. De fingerprint wordt
berekend uit `DeviceName` en `Bounds` van alle schermen.

Bij een gemaximaliseerd venster wordt nu ook de doelmonitor onthouden, zodat herstel op dezelfde monitor gebeurt.

## Build en test

Build:

```sh
dotnet build ZAAP.net/ZAAP.net.sln -p:EnableWindowsTargeting=true
```

Tests compileren op Linux, maar WinForms/WindowsDesktop runtime-validatie lukt
daar niet. Interactieve validatie van de UI en Windows Preview Handlers moet op
Windows gebeuren.

## Vervolgdocumenten

- `PLAN.md`: alleen openstaande punten en bug backlog
- `archives.PLAN.md`: ontwerpplan voor archive preview
