feat(openen): meerdere bestanden tegelijk aanwijzen en openen (#1928) #1935

Merged
brenno merged 8 commits from feat/open-multiple-files into main 2026-09-03 08:11:38 +00:00
Owner

Samenvatting

Wie drie presentaties wilde openen, liep de hele openen-dialoog drie keer door (#1928) — terwijl een stapel bestanden op het venster slepen al wél werkte.

De lijst kent nu dezelfde handgreep als de slidelijst, waar de gebruiker hem al kent: Shift is een bereik, Ctrl/Cmd voegt er een toe of haalt er een af, en een kale klik opent zoals altijd meteen dat ene bestand. Zodra er iets is aangewezen verschijnt Openen (n); de aangewezen rijen dragen een vinkje in plaats van het pijltje — dat pijltje belooft "dit opent", en dat is dan niet meer waar. Achter Bladeren… neemt ook de systeemkiezer een meervoudige selectie aan.

Keuzes die uitleg verdienen

  • De selectie wordt op pad bewaard, niet op rij-index. De zichtbare lijst verschuift bij elke aanslag in het zoekveld en bij elke wissel van het soortfilter; een index zou dan een ander bestand aanwijzen.
  • De dia-index blijft aan één bestand hangen. Een zoektreffer wijst een dia aan binnen dát bestand; bij een stapel is er geen treffer om naartoe te springen.
  • Eén onleesbaar bestand breekt de rest niet af, dezelfde afspraak als bij sleep-en-neerzetten. De rijke weigering met de importroute als uitweg blijft voorbehouden aan het enkele bestand: die biedt precies dát bestand ter import aan, en bij een stapel weet niemand welk.
  • Het macOS-kanaal levert voortaan altijd een lijst, ook voor één bestand, zodat er maar één vorm over de brug reist; pickUnfilteredMacFile is een dunne wikkel geworden.
  • Klasseplafond FileService +26. Het werk zelf ligt al top-level (_pickPathsGated); wat in de klasse overblijft is de dialoogtitel, en die komt uit _d() — een instantiemethode, want de taalcode hangt aan deze klasse.

Bewaker

Uitgevoerd, want dit raakt een publieke belofte in de interface en de documentatie.

  • Formaat, opslag, afhankelijkheden en uitgaand verkeer: onveranderd. Er komt niets nieuws in het .md, er wordt geen nieuwe partij vertrouwd.
  • Eén bevinding, onder waarde 7 (bediening met alleen het toetsenbord): de bestandslijst in dit scherm is niet met het toetsenbord te bedienen — 25 keer Tab met telkens een kale Enter activeert geen enkele rij. Dat is bestaand gedrag, niet door deze PR veroorzaakt: ook het openen van één bestand uit deze lijst kon al niet zonder muis. De nieuwe meervoudige selectie erft die beperking. Apart ingediend als #1934, met wat er nodig lijkt (focusvolgorde, pijltjesnavigatie, Enter opent, en een toetsenbord-equivalent voor de selectie).

Testplan

  • make check groen (volledige suite, dekkingsvloeren, goldens) — daarna gerebaseerd op verse main en make check-static + de openroute-tests opnieuw groen
  • make check-secrets — 0 leaks (gitleaks + trufflehog)
  • make sast — 0 findings (semgrep, lokale regels)
  • make l10n-check groen; 2 nieuwe strings × 31 talen via make add-l10n
  • Mutatie-geproefd. Modifiers negeren → vier tests rood; het bereik terugbrengen tot één rij → precies de bereiktest; alleen het eerste pad openen → precies de reis-test; de hint zonder Expanded → alle vier de overflow-viewports
  • Het openen-dialoog mét selectie geregistreerd in overflow_stress_test — drie knoppen in de voet plus de uitlegregel, getoetst op 200% tekst over vier viewports
  • Beeldkeuring in de draaiende app: NIET gedaan. De toegangsvraag voor computer-use is geweigerd, dus ik heb de dialoog niet met eigen ogen gezien. Wat wél mechanisch getoetst is: geen overflow bij 200% tekst, en het zichtbare verschil tussen een aangewezen en een gewone rij (vinkje in plaats van pijltje). De kleuren komen uit thema-tokens (AppTheme.infoBg, AppTheme.accentFg), geen eigen palet — maar of het er in licht én donker góed uitziet, is niet met eigen ogen vastgesteld.

Native code

macos/Runner/AppDelegate.swift krijgt allowsMultipleSelection en geeft een array terug. Die kant draait niet onder flutter test; het Dart-contract eromheen is wél getoetst (open_file_channel_test.dart, drie tests erbij).

🤖 Generated with Claude Code

## Samenvatting Wie drie presentaties wilde openen, liep de hele openen-dialoog drie keer door (#1928) — terwijl een stapel bestanden op het venster slepen al wél werkte. De lijst kent nu dezelfde handgreep als de slidelijst, waar de gebruiker hem al kent: **Shift** is een bereik, **Ctrl/Cmd** voegt er een toe of haalt er een af, en een **kale klik opent zoals altijd meteen** dat ene bestand. Zodra er iets is aangewezen verschijnt *Openen (n)*; de aangewezen rijen dragen een vinkje in plaats van het pijltje — dat pijltje belooft "dit opent", en dat is dan niet meer waar. Achter *Bladeren…* neemt ook de systeemkiezer een meervoudige selectie aan. ## Keuzes die uitleg verdienen - **De selectie wordt op pad bewaard, niet op rij-index.** De zichtbare lijst verschuift bij elke aanslag in het zoekveld en bij elke wissel van het soortfilter; een index zou dan een ander bestand aanwijzen. - **De dia-index blijft aan één bestand hangen.** Een zoektreffer wijst een dia aan binnen dát bestand; bij een stapel is er geen treffer om naartoe te springen. - **Eén onleesbaar bestand breekt de rest niet af**, dezelfde afspraak als bij sleep-en-neerzetten. De rijke weigering met de importroute als uitweg blijft voorbehouden aan het enkele bestand: die biedt precies dát bestand ter import aan, en bij een stapel weet niemand welk. - **Het macOS-kanaal levert voortaan altijd een lijst**, ook voor één bestand, zodat er maar één vorm over de brug reist; `pickUnfilteredMacFile` is een dunne wikkel geworden. - **Klasseplafond `FileService` +26.** Het werk zelf ligt al top-level (`_pickPathsGated`); wat in de klasse overblijft is de dialoogtitel, en die komt uit `_d()` — een instantiemethode, want de taalcode hangt aan deze klasse. ## Bewaker Uitgevoerd, want dit raakt een publieke belofte in de interface en de documentatie. - Formaat, opslag, afhankelijkheden en uitgaand verkeer: onveranderd. Er komt niets nieuws in het `.md`, er wordt geen nieuwe partij vertrouwd. - **Eén bevinding, onder waarde 7 (bediening met alleen het toetsenbord):** de bestandslijst in dit scherm is niet met het toetsenbord te bedienen — 25 keer Tab met telkens een kale Enter activeert geen enkele rij. Dat is **bestaand gedrag, niet door deze PR veroorzaakt**: ook het openen van één bestand uit deze lijst kon al niet zonder muis. De nieuwe meervoudige selectie erft die beperking. Apart ingediend als #1934, met wat er nodig lijkt (focusvolgorde, pijltjesnavigatie, Enter opent, en een toetsenbord-equivalent voor de selectie). ## Testplan - [x] `make check` groen (volledige suite, dekkingsvloeren, goldens) — daarna gerebaseerd op verse main en `make check-static` + de openroute-tests opnieuw groen - [x] `make check-secrets` — 0 leaks (gitleaks + trufflehog) - [x] `make sast` — 0 findings (semgrep, lokale regels) - [x] `make l10n-check` groen; 2 nieuwe strings × 31 talen via `make add-l10n` - [x] **Mutatie-geproefd.** Modifiers negeren → vier tests rood; het bereik terugbrengen tot één rij → precies de bereiktest; alleen het eerste pad openen → precies de reis-test; de hint zonder `Expanded` → alle vier de overflow-viewports - [x] Het openen-dialoog mét selectie geregistreerd in `overflow_stress_test` — drie knoppen in de voet plus de uitlegregel, getoetst op 200% tekst over vier viewports - [ ] **Beeldkeuring in de draaiende app: NIET gedaan.** De toegangsvraag voor computer-use is geweigerd, dus ik heb de dialoog niet met eigen ogen gezien. Wat wél mechanisch getoetst is: geen overflow bij 200% tekst, en het zichtbare verschil tussen een aangewezen en een gewone rij (vinkje in plaats van pijltje). De kleuren komen uit thema-tokens (`AppTheme.infoBg`, `AppTheme.accentFg`), geen eigen palet — maar of het er in licht én donker góed uitziet, is niet met eigen ogen vastgesteld. ## Native code `macos/Runner/AppDelegate.swift` krijgt `allowsMultipleSelection` en geeft een array terug. Die kant draait niet onder `flutter test`; het Dart-contract eromheen is wél getoetst (`open_file_channel_test.dart`, drie tests erbij). 🤖 Generated with [Claude Code](https://claude.com/claude-code)
De kiezerlaag kon precies één pad opleveren. Onder pickMarkdownFile ligt nu
_pickPathsGated, dat met allowsMultiple een stapel teruggeeft: op macOS via het
eigen NSOpenPanel (allowsMultipleSelection), elders via FilePicker.pickFiles.

Het kanaal levert voortaan altijd een lijst — ook voor één bestand — zodat er
maar één vorm over de brug reist; pickUnfilteredMacFile is een dunne wikkel om
de meervoudige variant. De platformpoort en de macOS-omweg met lege
allowedContentTypes blijven staan waar ze stonden.

Niemand gebruikt pickMarkdownFiles nog; de openroute volgt in de volgende stap.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Wie drie presentaties wilde openen, liep de hele openen-dialoog drie keer door
— terwijl drie bestanden erin slepen al wél werkte. De lijst kent nu dezelfde
handgreep als de slidelijst: Shift = bereik, Ctrl/Cmd = toevoegen/verwijderen,
een kale klik opent zoals altijd meteen dat ene bestand. Zodra er iets is
aangewezen verschijnt "Openen (n)"; de aangewezen rijen dragen een vinkje en de
info-tint van het actieve thema.

OpenSearchResult draagt daarom een lijst paden in plaats van één pad. De
dia-index blijft aan één bestand hangen: bij een stapel is er geen zoektreffer
om naartoe te springen. Elk pad opent in zijn eigen tabblad, en één onleesbaar
bestand breekt de rest niet af — dezelfde afspraak als bij sleep-en-neerzetten.
De rijke weigering met de importroute als uitweg blijft voor het enkele bestand:
die biedt precies dát bestand ter import aan, en bij een stapel weet niemand
welk.

De selectie wordt op pad bewaard en niet op rij-index: de zichtbare lijst
verschuift bij elke aanslag in het zoekveld en bij elke wissel van het
soortfilter.

Twee nieuwe strings, in alle 31 talen (make add-l10n).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Zeven tests: de kale klik die één bestand opent zoals altijd, Ctrl- en
Cmd-klik die aanwijzen zonder te openen, opnieuw Ctrl-klikken dat een rij er
weer afhaalt, Shift-klik dat het bereik meeneemt, de afwezige knop zonder
selectie mét de vindbaarheidsregel, en de hele reis door de echte shell:
Ctrl+O, twee rijen aanwijzen, "Openen (2)", twee tabbladen.

Elke test is met een mutatie geproefd. Modifiers negeren maakt er vier rood;
het bereik terugbrengen tot één rij precies de bereiktest; alleen het eerste
pad openen precies de reis-test.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
USER_GUIDE (en+nl), SOURCE_MAP voor de dialoog en het macOS-kanaal, SHORTCUTS
bij Ctrl/Cmd+O, en de Unreleased-regel in het logboek.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Het werk zelf ligt al top-level (_pickPathsGated); wat in de klasse overblijft
is de dialoogtitel, en die komt uit _d() — een instantiemethode, want de
taalcode hangt aan deze klasse. Reden staat bij de basislijnregel.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
De voet draagt sinds #1928 drie knoppen (Bladeren…, Annuleren, Openen (n)) plus
de regel die de meervoudige selectie uitlegt. Mét selectie geregistreerd, want
de derde knop bestaat pas dan — en juist die maakt de rij te lang.

Geproefd: de hint zonder Expanded laat alle vier de viewports omvallen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
De mock gaf een String terug waar de Dart-kant nu een lijst leest, dus de
bestaande test viel om. Het contract is bewust veranderd: één vorm over de
brug. Drie tests erbij — de wikkel vraagt geen meervoudige selectie aan en
neemt het eerste van meerdere, en de meervoudige variant vraagt het wél aan en
levert alles.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
test(openen): een aangewezen rij is zichtbaar anders (#1928)
All checks were successful
scans / scans (pull_request) Successful in 2m12s
static-gate / static-gate (pull_request) Successful in 5m35s
556d163f96
Het pijltje belooft "dit opent"; bij een aangewezen rij is dat niet meer waar
en maakt het plaats voor een vinkje. Zonder dat verschil is de selectie
onzichtbaar, en dat is precies wat een waardetest niet ziet.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
brenno force-pushed feat/open-multiple-files from 556d163f96
All checks were successful
scans / scans (pull_request) Successful in 2m12s
static-gate / static-gate (pull_request) Successful in 5m35s
to e7a84976a6
All checks were successful
scans / scans (pull_request) Successful in 4m7s
static-gate / static-gate (pull_request) Successful in 10m30s
2026-09-03 07:59:29 +00:00
Compare
brenno merged commit b095213274 into main 2026-09-03 08:11:38 +00:00
Sign in to join this conversation.
No description provided.