Regenerate the matrix, the gesture book and the manual page for the duplicates review

This commit is contained in:
2026-09-26 07:20:19 -04:00
parent 7c9a4ee358
commit 6640ce0ca8
4 changed files with 243 additions and 103 deletions
File diff suppressed because one or more lines are too long
+93 -29
View File
@@ -5,7 +5,7 @@
Every entry here is extracted from the comment beside the code that implements it, so this file cannot describe a gesture the application does not have. Add one by writing a `GESTURE:` block next to the implementation; there is nowhere else to write it.
68 gestures, in 5 places.
74 gestures, in 7 places.
## Develop
@@ -28,7 +28,7 @@ Sampling a neutral is the first move of the tonal pass — every colour judgemen
Anchored on the fingers' midpoint, and on the pointer, so the gesture reads as magnifying the picture rather than sliding it about. Double-tap is the way to an exact 1:1; this is the way to everything in between. Past 1:1 the pixels are shown as they are, square and unsmoothed; below it, filtered.
<sub>`ui/dr-ui/ui/app.slint:1895`</sub>
<sub>`ui/dr-ui/ui/app.slint:1907`</sub>
### Move a magnified photograph about
@@ -39,7 +39,7 @@ Anchored on the fingers' midpoint, and on the pointer, so the gesture reads as m
Only once there is something outside the viewport to reach, which is why the cursor becomes a hand exactly then. The view is clamped to the frame: panning past the edge would show undefined area beside the photograph, and that reads as a rendering fault rather than as the end of the picture.
<sub>`ui/dr-ui/ui/app.slint:1991`</sub>
<sub>`ui/dr-ui/ui/app.slint:2003`</sub>
### Paint a mask by hand
@@ -49,7 +49,7 @@ Only once there is something outside the viewport to reach, which is why the cur
A model's mask stops inside a shoulder and leaks into the hair, and no single edge control fixes two errors that go opposite ways. The whole stroke is one step in the history, so taking a mark back costs one press however long it took to make.
<sub>`ui/dr-ui/ui/app.slint:2082`</sub>
<sub>`ui/dr-ui/ui/app.slint:2094`</sub>
### Open this list
@@ -59,7 +59,7 @@ A model's mask stops inside a shoulder and leaks into the hair, and no single ed
Most of the keys are develop's, and a reference that could only be opened from the grid had to be looked up before opening the photograph they were wanted for.
<sub>`ui/dr-ui/ui/app.slint:2308`</sub>
<sub>`ui/dr-ui/ui/app.slint:2320`</sub>
### Take back the last change
@@ -70,7 +70,7 @@ Most of the keys are develop's, and a reference that could only be opened from t
A whole drag is one step, so undo takes back a decision rather than a frame of a gesture. The list is there because arriving six steps back costs what arriving from one does.
<sub>`ui/dr-ui/ui/app.slint:2338`</sub>
<sub>`ui/dr-ui/ui/app.slint:2350`</sub>
### Do it again after taking it back
@@ -79,7 +79,7 @@ A whole drag is one step, so undo takes back a decision rather than a frame of a
- **Keyboard** — `Ctrl+Shift+Z`, or `Ctrl+Y`
- **See it** — [in the manual](manual/README.md#history-snapshots-presets)
<sub>`ui/dr-ui/ui/app.slint:2352`</sub>
<sub>`ui/dr-ui/ui/app.slint:2364`</sub>
### Remove a repair
@@ -87,7 +87,7 @@ A whole drag is one step, so undo takes back a decision rather than a frame of a
- **Pointer** — Click it, then Delete Repair
- **Keyboard** — `Delete` or `Backspace`, while repairing
<sub>`ui/dr-ui/ui/app.slint:2372`</sub>
<sub>`ui/dr-ui/ui/app.slint:2384`</sub>
### Copy the settings from this photograph
@@ -98,7 +98,7 @@ A whole drag is one step, so undo takes back a decision rather than a frame of a
The button is the copy that has to work: a tablet has no modifier key to hold and no menu bar to hang the action from. The shortcut is an accelerator for a control that is on screen either way.
<sub>`ui/dr-ui/ui/app.slint:2391`</sub>
<sub>`ui/dr-ui/ui/app.slint:2403`</sub>
### Paste the settings onto this photograph
@@ -109,7 +109,7 @@ The button is the copy that has to work: a tablet has no modifier key to hold an
The button names what would be pasted — "3 adjustments", and whether the crop is coming with it — which the shortcut cannot say. Both paste the same scope.
<sub>`ui/dr-ui/ui/app.slint:2404`</sub>
<sub>`ui/dr-ui/ui/app.slint:2416`</sub>
### Choose which kinds of edit a copy carries
@@ -120,7 +120,7 @@ The button names what would be pasted — "3 adjustments", and whether the crop
Lightroom's Copy Settings. Pasting a look across a shoot usually means leaving each frame's crop and rotation alone, and that is a choice to make at the moment of copying.
<sub>`ui/dr-ui/ui/app.slint:2422`</sub>
<sub>`ui/dr-ui/ui/app.slint:2434`</sub>
### Export this photograph as the last one was
@@ -131,7 +131,7 @@ Lightroom's Copy Settings. Pasting a look across a shoot usually means leaving e
Every export runs on the defaults in Settings, so "as the last one was" is what the button already does. The chord is Lightroom's and darktable's, kept so hands that learned it there need not learn it again.
<sub>`ui/dr-ui/ui/app.slint:2447`</sub>
<sub>`ui/dr-ui/ui/app.slint:2459`</sub>
### Choose how to export, then export
@@ -142,7 +142,7 @@ Every export runs on the defaults in Settings, so "as the last one was" is what
The export sheet is the export defaults alone with an Export button. What is chosen there is kept, so it is also what the next Ctrl+Shift+E uses.
<sub>`ui/dr-ui/ui/app.slint:2460`</sub>
<sub>`ui/dr-ui/ui/app.slint:2472`</sub>
### Keep a crop that leaves a mask outside
@@ -150,7 +150,7 @@ The export sheet is the export defaults alone with an Export button. What is cho
- **Pointer** — Press "Keep crop" on the notice, or "Undo crop" to take it back
- **Keyboard** — `Enter` keeps it; `Ctrl+Z` takes the crop back, like any other step
<sub>`ui/dr-ui/ui/app.slint:2525`</sub>
<sub>`ui/dr-ui/ui/app.slint:2537`</sub>
### Go back to the grid
@@ -160,7 +160,7 @@ The export sheet is the export defaults alone with an Export button. What is cho
Lightroom's key for the grid. Escape gets there too, but a step at a time — out of a mode, then out of a zoom — where this goes straight back.
<sub>`ui/dr-ui/ui/app.slint:2542`</sub>
<sub>`ui/dr-ui/ui/app.slint:2554`</sub>
### Nudge the control last moved
@@ -170,7 +170,7 @@ Lightroom's key for the grid. Escape gets there too, but a step at a time — ou
Lightroom's keys for the selected slider. There is no focus ring on a slider here, so "selected" is the last one moved — the same control `R` puts back — which covers the framing sliders, perspective included, as well as the adjustments.
<sub>`ui/dr-ui/ui/app.slint:2571`</sub>
<sub>`ui/dr-ui/ui/app.slint:2583`</sub>
### Change which group of adjustments is on screen
@@ -181,7 +181,7 @@ Lightroom's keys for the selected slider. There is no focus ring on a slider her
The groups are whatever the operation set declares itself to be about, so there are as many as the pipeline has and no key can be assigned to one of them by name. Stepping is the binding that survives a node being added.
<sub>`ui/dr-ui/ui/app.slint:2599`</sub>
<sub>`ui/dr-ui/ui/app.slint:2611`</sub>
### Look at the photograph at 1:1
@@ -192,7 +192,7 @@ The groups are whatever the operation set declares itself to be about, so there
Noise reduction and capture sharpening are judgements about single pixels, and a fitted view averages several of the file's into each one on screen — so the frame looks softer than it is and the correction goes too far. The point and the magnification survive opening the next photograph, which is what makes checking the same eye across forty portraits forty keystrokes rather than forty pans. From 1:1 on the photograph is drawn as its own pixels, each a hard-edged square, rather than smoothed into a blur.
<sub>`ui/dr-ui/ui/app.slint:2635`</sub>
<sub>`ui/dr-ui/ui/app.slint:2647`</sub>
### Rate this photograph
@@ -200,7 +200,7 @@ Noise reduction and capture sharpening are judgements about single pixels, and a
- **Pointer** — Click a star in the top bar
- **Keyboard** — `0`–`5`
<sub>`ui/dr-ui/ui/app.slint:2692`</sub>
<sub>`ui/dr-ui/ui/app.slint:2704`</sub>
### Pick or reject this photograph
@@ -210,7 +210,7 @@ Noise reduction and capture sharpening are judgements about single pixels, and a
The grid's keys, on the photograph that is open (FR-UI-5, 2026-09-19). Judging here does not move on to the next frame: that belongs to culling, and in develop the photograph in front of you is the one being worked on.
<sub>`ui/dr-ui/ui/app.slint:2698`</sub>
<sub>`ui/dr-ui/ui/app.slint:2710`</sub>
### Give this photograph a colour label
@@ -221,7 +221,7 @@ The grid's keys, on the photograph that is open (FR-UI-5, 2026-09-19). Judging h
The grid's keys, on the photograph that is open, so labelling while stepping through a folder is one hand's work. The bar names the label in words beside its mark.
<sub>`ui/dr-ui/ui/app.slint:2728`</sub>
<sub>`ui/dr-ui/ui/app.slint:2740`</sub>
### Move to the next or previous photograph
@@ -232,7 +232,7 @@ The grid's keys, on the photograph that is open, so labelling while stepping thr
The edit on screen is saved on the way out, so stepping through a folder is as much a departure as going back to the grid and loses nothing. A and D as well as the arrows, so the left hand steps along the roll while the right stays on the mouse.
<sub>`ui/dr-ui/ui/app.slint:2753`</sub>
<sub>`ui/dr-ui/ui/app.slint:2765`</sub>
### See the photograph before you edited it
@@ -243,7 +243,7 @@ The edit on screen is saved on the way out, so stepping through a folder is as m
Held rather than toggled, and no split screen: a split halves the working image on the tablet the column was sized for, and the comparison photographers describe making is a flick back and forth. It takes no history step, so checking whether a frame is overcooked costs nothing to undo afterwards.
<sub>`ui/dr-ui/ui/app.slint:2883`</sub>
<sub>`ui/dr-ui/ui/app.slint:2895`</sub>
### Put one control back to its default
@@ -327,7 +327,7 @@ The question a correction raises is whether it did what it was for — whether t
One key for "up one", innermost first: a question before the sheet under it, a sheet before the view, a view before the library. Nothing is left behind a dialogue that the key walked straight past.
<sub>`ui/dr-ui/ui/app.slint:981`</sub>
<sub>`ui/dr-ui/ui/app.slint:986`</sub>
### Do what a sheet offers
@@ -335,7 +335,7 @@ One key for "up one", innermost first: a question before the sheet under it, a s
- **Pointer** — Press its button — Export, or Copy
- **Keyboard** — `Enter`, on the export and copy sheets
<sub>`ui/dr-ui/ui/app.slint:991`</sub>
<sub>`ui/dr-ui/ui/app.slint:996`</sub>
## Collections sidebar
@@ -347,7 +347,7 @@ One key for "up one", innermost first: a question before the sheet under it, a s
The tree is inside a Flickable, which claims any drag beginning inside it — so with a finger a drag on a row is a scroll until something says otherwise. The hold is that something, and it is what every mobile list already uses to pick a row up. The row lifts the moment it fires, so the gesture says it has been understood before anything moves.
<sub>`ui/dr-ui/ui/collections.slint:351`</sub>
<sub>`ui/dr-ui/ui/collections.slint:352`</sub>
### Act on a collection — rename, nest, un-nest, delete
@@ -357,7 +357,7 @@ The tree is inside a Flickable, which claims any drag beginning inside it — so
The hold arms a drag and opens this menu, and which one you get is decided by whether you moved — the same fork the grid uses. One menu for everything done to a row, because there is one hold per row: while the hold opened the offline question by itself, nothing else the tree can do had a touch route.
<sub>`ui/dr-ui/ui/collections.slint:363`</sub>
<sub>`ui/dr-ui/ui/collections.slint:364`</sub>
### Take a collection back out of the one it is nested in
@@ -367,7 +367,7 @@ The hold arms a drag and opens this menu, and which one you get is decided by wh
Nesting is a drag of one row onto another, and its inverse had no gesture at all: "All photographs" refused every drop, which is right for a photograph — it is already in the library — and wrong for a collection, which has a top level to be returned to. Without it a collection dragged into another was in there permanently.
<sub>`ui/dr-ui/ui/collections.slint:374`</sub>
<sub>`ui/dr-ui/ui/collections.slint:375`</sub>
### Rename a collection
@@ -378,7 +378,59 @@ Nesting is a drag of one row onto another, and its inverse had no gesture at all
Double-click is what a file manager and a Lightroom panel use for the same thing, so it needs no discovering — but nothing on screen says so, which is what the menu item is for.
<sub>`ui/dr-ui/ui/collections.slint:388`</sub>
<sub>`ui/dr-ui/ui/collections.slint:389`</sub>
### Review duplicate originals
- **Touch** — Tap "Duplicate originals" under the trash
- **Pointer** — Click "Duplicate originals" under the trash
- **See it** — [in the manual](manual/README.md#duplicate-originals)
Under the trash because the trash is where the spare copies go, and only while the catalog holds any: a row that is always there and usually empty is noise.
<sub>`ui/dr-ui/ui/collections.slint:870`</sub>
## Duplicate originals
### Check duplicate originals are the same file
- **Touch** — Tap "Check"
- **Pointer** — Click "Check"
- **See it** — [in the manual](manual/README.md#duplicate-originals)
Nothing is moved on the catalog's say-so. The check reads the first and last megabyte of each copy and its sidecar, keeps what it read, and drops any group whose bytes or edits differ.
<sub>`ui/dr-ui/ui/duplicates.slint:233`</sub>
### Move the spare copies to the trash
- **Touch** — Tap "Move N copies to trash"
- **Pointer** — Click "Move N copies to trash"
- **See it** — [in the manual](manual/README.md#duplicate-originals)
The one verb, named with its count, and off until a check has proved something. Each group is merged onto the copy that stays and the others go to the trash together or not at all; the trash view gives them back.
<sub>`ui/dr-ui/ui/duplicates.slint:248`</sub>
### Choose which copy of a duplicate stays
- **Touch** — Tap the copy's path
- **Pointer** — Click the copy's path
- **See it** — [in the manual](manual/README.md#duplicate-originals)
The rule picks the copy outside a backup folder that still has the camera's name. The path is the evidence, so the path is what is tapped to overrule it.
<sub>`ui/dr-ui/ui/duplicates.slint:313`</sub>
### Leave a duplicate group as it is
- **Touch** — Untick "Include" on the group
- **Pointer** — Untick "Include" on the group
- **See it** — [in the manual](manual/README.md#duplicate-originals)
The plan is every group the check proved; a group you want to keep in two places is taken out of it rather than argued with.
<sub>`ui/dr-ui/ui/duplicates.slint:323`</sub>
## People
@@ -704,3 +756,15 @@ A scoped grid of two hundred frames is two hundred taps otherwise, and "all of t
The badge on a cell says a photograph is filed in three collections and never which. This is the sheet that names them, and the only way out of one the grid is not currently scoped to.
<sub>`ui/dr-ui/ui/library.slint:5163`</sub>
## Settings
### Review duplicate originals
- **Touch** — Tap "Review duplicate originals"
- **Pointer** — Click "Review duplicate originals"
- **See it** — [in the manual](manual/README.md#duplicate-originals)
Beside the other whole-library passes, because it is one; the sidebar offers the same page under the trash.
<sub>`ui/dr-ui/ui/settings.slint:530`</sub>
+27
View File
@@ -110,6 +110,7 @@ th { color: var(--ink-dim); font-weight: 600; }
<li><a href="#selecting-several">Selecting several</a></li>
<li><a href="#collections">Collections</a></li>
<li><a href="#bursts">Bursts</a></li>
<li><a href="#duplicate-originals">Duplicate originals</a></li>
</ul>
</li>
<li><a href="#developing-a-photograph">Developing a photograph</a>
@@ -207,6 +208,32 @@ the grid, and again to fold it back. A folded burst shows its earliest frame;
to have it show another, open it and click the ring on the frame you want.</p>
<p>With faces indexed, narrowing the grid to a person puts <code>Eyes open</code> beside
their name on the filter bar, which leaves out the frames where they blinked.</p>
<h3 id="duplicate-originals">Duplicate originals</h3>
<p>A library put together by hand often holds the same RAW more than once — a
dated folder, a <code>bck</code> folder beside it, a renamed copy another program
exported. When the catalog finds files with the same camera, capture time
and size in more than one place, <code>Duplicate originals</code> appears under the
trash in the sidebar with how many there are; Settings offers the same page
beside the other whole-library passes.</p>
<p>The page lists each group with its picture and its paths. One copy is
marked <code>Stays</code>: the one outside a folder named like a backup (<code>bck</code>,
<code>backup</code>, <code>copy</code>, <code>old</code>…), then the one still named the way the camera named
it (<code>_MG_4623</code>, <code>IMG_0001</code>, <code>DSC_0042</code>), then the one catalogued first. Tap
another path to keep that copy instead, and untick <code>Include</code> to leave a
group alone.</p>
<p>Nothing moves until <code>Check</code> has read the first and last megabyte of every
copy and each copy's sidecar. A group whose files differ, or whose copies
carry two different edits, is marked skipped and says why — two edits of
one frame are kept for virtual copies. What the check reads is kept, so a
second visit costs nothing. The line under each group says what the copy
that stays will gain: the highest rating, every keyword and collection, a
flag or label the copies agree on, faces and the names on them, and the
edit if only a copy had one. Where the copies disagree on a flag or a
label, the one that stays keeps its own and the line says so.</p>
<p><code>Move N copies to trash</code> does it, one group at a time: each group is merged
and its spare copies moved together, or not at all. The copies go to the
trash, not away — select them in the trash view and <code>Restore</code> puts them
back where they were.</p>
<h2 id="developing-a-photograph">Developing a photograph</h2>
<p>Click a thumbnail to open it. The column on the right is every adjustment;
the strip at its head narrows it to one group.</p>