LRC-LIB-KEYWORDS: a chip's menu acts on the selection
The chip menu offered Delete Keyword, which takes the keyword off every photo in the library, beside "Remove from Photo". It now acts on the selected photos only: Add to All Selected Photos (for a keyword only some have), Remove from Selected Photos, Show Photos with Keyword, and Edit Keyword Tag… (the Keyword List's dialog, for renaming too). Deleting a keyword from the library is the Keyword List's. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
4cb024164e
commit
a3b7c4caf4
|
|
@ -1911,5 +1911,6 @@
|
|||
"Delete Keyword…": "Stichwort löschen…",
|
||||
"Drop here for the top level": "Hier ablegen für die oberste Ebene",
|
||||
"Their photos and the keywords below them come together under one keyword.": "Ihre Fotos und die Stichwörter darunter kommen unter einem Stichwort zusammen.",
|
||||
"Select photos to give them keywords.": "Wählen Sie Fotos aus, um ihnen Stichwörter zu geben."
|
||||
"Select photos to give them keywords.": "Wählen Sie Fotos aus, um ihnen Stichwörter zu geben.",
|
||||
"Add to All Selected Photos": "Allen ausgewählten Fotos hinzufügen"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1756,5 +1756,6 @@
|
|||
"Delete Keyword…": "Eliminar palabra clave…",
|
||||
"Drop here for the top level": "Soltar aquí para el nivel superior",
|
||||
"Their photos and the keywords below them come together under one keyword.": "Sus fotos y las palabras clave que contienen quedan bajo una sola palabra clave.",
|
||||
"Select photos to give them keywords.": "Selecciona fotos para darles palabras clave."
|
||||
"Select photos to give them keywords.": "Selecciona fotos para darles palabras clave.",
|
||||
"Add to All Selected Photos": "Añadir a todas las fotos seleccionadas"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1756,5 +1756,6 @@
|
|||
"Delete Keyword…": "キーワードを削除…",
|
||||
"Drop here for the top level": "ここにドロップすると最上位に移動",
|
||||
"Their photos and the keywords below them come together under one keyword.": "写真と下位のキーワードが1つのキーワードにまとめられます。",
|
||||
"Select photos to give them keywords.": "写真を選択するとキーワードを付けられます。"
|
||||
"Select photos to give them keywords.": "写真を選択するとキーワードを付けられます。",
|
||||
"Add to All Selected Photos": "選択したすべての写真に追加"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1756,5 +1756,6 @@
|
|||
"Delete Keyword…": "Excluir palavra-chave…",
|
||||
"Drop here for the top level": "Solte aqui para o nível superior",
|
||||
"Their photos and the keywords below them come together under one keyword.": "Suas fotos e as palavras-chave abaixo delas ficam sob uma só palavra-chave.",
|
||||
"Select photos to give them keywords.": "Selecione fotos para dar palavras-chave a elas."
|
||||
"Select photos to give them keywords.": "Selecione fotos para dar palavras-chave a elas.",
|
||||
"Add to All Selected Photos": "Adicionar a todas as fotos selecionadas"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1430,5 +1430,6 @@
|
|||
"Drop here for the top level": "Отпустите здесь для верхнего уровня",
|
||||
"Their photos and the keywords below them come together under one keyword.": "Их фото и вложенные ключевые слова объединятся под одним ключевым словом.",
|
||||
"Select photos to give them keywords.": "Выберите фото, чтобы назначить им ключевые слова.",
|
||||
"Person": "Человек"
|
||||
"Person": "Человек",
|
||||
"Add to All Selected Photos": "Добавить ко всем выбранным фото"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1756,5 +1756,6 @@
|
|||
"Delete Keyword…": "删除关键字…",
|
||||
"Drop here for the top level": "拖放到此处以移至顶层",
|
||||
"Their photos and the keywords below them come together under one keyword.": "它们的照片和下级关键字将合并到同一个关键字下。",
|
||||
"Select photos to give them keywords.": "选择照片以为其添加关键字。"
|
||||
"Select photos to give them keywords.": "选择照片以为其添加关键字。",
|
||||
"Add to All Selected Photos": "添加到所有所选照片"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1756,5 +1756,6 @@
|
|||
"Delete Keyword…": "刪除關鍵字…",
|
||||
"Drop here for the top level": "拖放到此處以移至最上層",
|
||||
"Their photos and the keywords below them come together under one keyword.": "它們的照片與下層關鍵字將合併到同一個關鍵字下。",
|
||||
"Select photos to give them keywords.": "選取照片以加入關鍵字。"
|
||||
"Select photos to give them keywords.": "選取照片以加入關鍵字。",
|
||||
"Add to All Selected Photos": "加入所有選取的照片"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,30 @@ use crate::LightcraftApp;
|
|||
use crate::theme::Tokens;
|
||||
use crate::widgets::register;
|
||||
|
||||
/// A chip's menu: it acts on the selected photos (deleting a keyword from the whole library is the
|
||||
/// Keyword List's).
|
||||
fn menu(app: &mut LightcraftApp, ui: &mut egui::Ui, chip: &Chip) {
|
||||
let item = |ui: &mut egui::Ui, id: &str, label: &str| {
|
||||
let r = ui.button(label);
|
||||
register(ui.ctx(), format!("keywordChipMenu:{id}"), r.rect);
|
||||
r.clicked()
|
||||
};
|
||||
if !chip.on_all() && item(ui, "add", crate::i18n::tr("Add to All Selected Photos")) {
|
||||
let _ = app.run("photo.setMeta", json!({"addKeywords": [chip.path]}));
|
||||
}
|
||||
if item(ui, "remove", crate::i18n::tr("Remove from Selected Photos")) {
|
||||
let _ = app.run("photo.setMeta", json!({"removeKeywords": [chip.path]}));
|
||||
}
|
||||
if item(ui, "show", crate::i18n::tr("Show Photos with Keyword")) {
|
||||
super::left::browse_all_photos(app, true);
|
||||
let _ = app.run("library.filter", json!({"keyword": chip.path}));
|
||||
}
|
||||
ui.separator();
|
||||
if item(ui, "edit", crate::i18n::tr("Edit Keyword Tag…")) {
|
||||
app.ui.dialog = Some(super::keyword_list::edit_dialog(app, &chip.path));
|
||||
}
|
||||
}
|
||||
|
||||
/// The selection's keywords as chips: the name (right-click for its menu), and × to take it off
|
||||
/// every selected photo. One only some of them have is marked with an asterisk.
|
||||
pub fn chip_row(app: &mut LightcraftApp, ui: &mut egui::Ui) {
|
||||
|
|
@ -43,22 +67,8 @@ pub fn chip_row(app: &mut LightcraftApp, ui: &mut egui::Ui) {
|
|||
}
|
||||
label
|
||||
});
|
||||
let k = chip.path.clone();
|
||||
shown.inner.context_menu(|ui| {
|
||||
if ui.button(crate::i18n::tr("Remove from Photo")).clicked() {
|
||||
let _ = app.run("photo.setMeta", json!({"removeKeywords": [k]}));
|
||||
}
|
||||
if ui.button(crate::i18n::tr("Show Photos with Keyword")).clicked() {
|
||||
let _ = app.run("library.filter", json!({"keyword": k}));
|
||||
}
|
||||
ui.separator();
|
||||
if ui.button(crate::i18n::tr("Rename Keyword…")).clicked() {
|
||||
app.ui.dialog = Some(crate::state::Dialog::RenameKeyword { from: k.clone(), to: k.clone() });
|
||||
}
|
||||
if ui.button(crate::i18n::tr("Delete Keyword")).clicked() {
|
||||
let _ = app.run("keyword.delete", json!({"keyword": k}));
|
||||
}
|
||||
});
|
||||
let chip = chip.clone();
|
||||
shown.inner.context_menu(|ui| menu(app, ui, &chip));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -67,3 +67,22 @@ fn only_the_cross_removes_a_keyword() {
|
|||
ask(&mut h, "ui.clickWidget", json!({"id": "keywordChipRemove:beach"}));
|
||||
assert!(ids.iter().all(|id| !keywords_of(&h, *id).contains(&"beach".to_string())), "× took it off both");
|
||||
}
|
||||
|
||||
/// A chip's menu acts on the selection, never on the whole library: give a keyword only some have
|
||||
/// to all of them, take it off them, show its photos, or edit it (Edit Keyword Tag). Deleting a
|
||||
/// keyword from every photo of the library is the Keyword List's.
|
||||
#[test]
|
||||
fn a_chips_menu_acts_on_the_selection() {
|
||||
let (mut h, ids) = two_selected();
|
||||
ask(&mut h, "ui.clickWidget", json!({"id": "keywordChip:Weddings", "button": "right"}));
|
||||
for item in ["add", "remove", "show", "edit"] {
|
||||
assert!(has(&h, &format!("keywordChipMenu:{item}")), "{item}");
|
||||
}
|
||||
assert!(!has(&h, "keywordChipMenu:delete"), "no library-wide delete");
|
||||
ask(&mut h, "ui.clickWidget", json!({"id": "keywordChipMenu:add"}));
|
||||
assert!(ids.iter().all(|id| keywords_of(&h, *id).contains(&"Weddings".to_string())), "given to both");
|
||||
ask(&mut h, "ui.clickWidget", json!({"id": "keywordChip:Weddings", "button": "right"}));
|
||||
assert!(!has(&h, "keywordChipMenu:add"), "both have it now");
|
||||
ask(&mut h, "ui.clickWidget", json!({"id": "keywordChipMenu:edit"}));
|
||||
assert!(matches!(&h.app.ui.dialog, Some(crate::state::Dialog::KeywordTag { editing: Some(k), .. }) if k == "Weddings"), "{:?}", h.app.ui.dialog);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue