diff --git a/docs/manual/README.md b/docs/manual/README.md index fb8e584..3a50876 100644 --- a/docs/manual/README.md +++ b/docs/manual/README.md @@ -145,6 +145,8 @@ 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. +![Two frames with a copy each in a bck folder, checked and proved the same, the copy that stays marked on each](media/duplicates.png) + `Move N copies to trash` 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 `Restore` puts them diff --git a/docs/manual/index.html b/docs/manual/index.html index 704157c..c6a5b5f 100644 --- a/docs/manual/index.html +++ b/docs/manual/index.html @@ -242,6 +242,7 @@ 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.

+
Two frames with a copy each in a bck folder, checked and proved the same, the copy that stays marked on each
Two frames with a copy each in a bck folder, checked and proved the same, the copy that stays marked on each

Move N copies to trash 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 Restore puts them diff --git a/docs/manual/media/duplicates.png b/docs/manual/media/duplicates.png new file mode 100644 index 0000000..3401462 --- /dev/null +++ b/docs/manual/media/duplicates.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:25bfb3abb610ae0a1e6bacfb6d63efac9cb617a0b4c2bde9cb5cedc2ecac2750 +size 72110 diff --git a/tools/manual/scenes.py b/tools/manual/scenes.py index 49d7e9e..57dc200 100755 --- a/tools/manual/scenes.py +++ b/tools/manual/scenes.py @@ -34,6 +34,7 @@ import fnmatch import inspect import os import re +import shutil import subprocess import sys import tempfile @@ -1182,6 +1183,67 @@ def settings(): pause(1.5) +# --- duplicate originals --------------------------------------------------- +DUPLICATED = [NY_FIRST, '_MG_8394'] # copied into a `bck` folder beside their own + + +def library_file(name): + """The path of file `name` in the demo library.""" + for root, _, files in os.walk(DEMO_LIBRARY): + if name in files: + return os.path.join(root, name) + raise FileNotFoundError(f'{name} is not in {DEMO_LIBRARY}') + + +@scene(media=['duplicates.png'], + sources=LIBRARY_SRC + ['ui/dr-ui/ui/duplicates.slint', 'ui/dr-ui/src/duplicates_ui.rs', + 'ui/dr-ui/src/duplicates.rs', 'core/dr-catalog/src/duplicates.rs']) +def duplicates(): + """The demo library holds no duplicates, so this makes two: copies of two + New York frames in a `bck` folder beside theirs, the way a hand-kept + backup sits. The app is restarted so its scan finds them, and the row + under the trash appears once the sweep has read their capture times. The + review is opened from there and checked, and the copies are deleted again + before the app is restarted on the library as it was. (The snapshot + record.sh restores would remove them too.)""" + made = [] + try: + for name in DUPLICATED: + src = library_file(f'{name}.CR2') + folder = os.path.join(os.path.dirname(src), 'bck') + os.makedirs(folder, exist_ok=True) + made.append(os.path.join(folder, f'{name}.CR2')) + shutil.copy2(src, made[-1]) + dr.stop() + dr.launch([]) + dr.wait_ready() + dr.wait_for('id:grid-scroll', 60) + dr.wait_for('Duplicate originals@Text', 300) + pause(1) + dr.click_on('Duplicate originals@Text') + dr.wait_for(f'Check {len(DUPLICATED)} groups@Button', 30) + pause(1) + dr.click_on(f'Check {len(DUPLICATED)} groups@Button') + dr.wait_gone(f'Check {len(DUPLICATED)} groups@Button', 60) + pause(3) + shot('duplicates') + dr.click_on('‹ Back@Button') + pause(1) + finally: + for f in made: + if os.path.exists(f): + os.remove(f) + for f in made: + d = os.path.dirname(f) + if os.path.isdir(d) and not os.listdir(d): + os.rmdir(d) + dr.stop() + dr.launch([]) + dr.wait_ready() + dr.wait_for('id:grid-scroll', 60) + pause(3) + + # --- running them ----------------------------------------------------------- def order(names): """`names` with their prerequisites, each once, prerequisites first."""