diff --git a/crates/ui-egui/src/i18n/cs.tsv b/crates/ui-egui/src/i18n/cs.tsv index 7addc3942..e39c7e595 100644 --- a/crates/ui-egui/src/i18n/cs.tsv +++ b/crates/ui-egui/src/i18n/cs.tsv @@ -3760,3 +3760,10 @@ navigator Zoom Zvětšení There are too many sets: delete one first. Sad je příliš mnoho: nejprve jednu smažte. set name název sady {set} (modified) {set} (změněno) + Accept and Go to Conflict Přijmout a přejít ke konfliktu + Changes undone. Změny vráceny. + Choose a new shortcut for this command, or leave it without one. Zvolte pro tento příkaz novou zkratku, nebo ho nechte bez ní. + Put this command's shortcuts back as they were Vrátit zkratky tohoto příkazu do původního stavu + Take the shortcut from the other command and select it Odebrat zkratku druhému příkazu a vybrat ho + Undo Changes Vrátit změny + {shortcut} is reserved by the system and can't be assigned. {shortcut} je vyhrazena systémem a nelze ji přiřadit. diff --git a/crates/ui-egui/src/i18n/de.tsv b/crates/ui-egui/src/i18n/de.tsv index d035e706b..c89998e0d 100644 --- a/crates/ui-egui/src/i18n/de.tsv +++ b/crates/ui-egui/src/i18n/de.tsv @@ -3150,3 +3150,10 @@ curves Smooth Glätten There are too many sets: delete one first. Zu viele Sätze: Löschen Sie zuerst einen. set name Name des Satzes {set} (modified) {set} (geändert) + Accept and Go to Conflict Übernehmen und zum Konflikt + Changes undone. Änderungen rückgängig gemacht. + Choose a new shortcut for this command, or leave it without one. Wählen Sie einen neuen Kurzbefehl für diesen Befehl oder lassen Sie ihn ohne. + Put this command's shortcuts back as they were Die Kurzbefehle dieses Befehls wiederherstellen + Take the shortcut from the other command and select it Den Kurzbefehl dem anderen Befehl entziehen und diesen auswählen + Undo Changes Änderungen rückgängig machen + {shortcut} is reserved by the system and can't be assigned. {shortcut} ist vom System reserviert und kann nicht zugewiesen werden. diff --git a/crates/ui-egui/src/i18n/el.tsv b/crates/ui-egui/src/i18n/el.tsv index 19129d715..6d5b69266 100644 --- a/crates/ui-egui/src/i18n/el.tsv +++ b/crates/ui-egui/src/i18n/el.tsv @@ -3850,3 +3850,10 @@ curves Smooth Εξομάλυνση There are too many sets: delete one first. Υπάρχουν πάρα πολλά σύνολα: διαγράψτε πρώτα ένα. set name όνομα συνόλου {set} (modified) {set} (τροποποιημένο) + Accept and Go to Conflict Αποδοχή και μετάβαση στη σύγκρουση + Changes undone. Οι αλλαγές αναιρέθηκαν. + Choose a new shortcut for this command, or leave it without one. Επιλέξτε νέα συντόμευση για αυτήν την εντολή ή αφήστε την χωρίς. + Put this command's shortcuts back as they were Επαναφορά των συντομεύσεων αυτής της εντολής όπως ήταν + Take the shortcut from the other command and select it Αφαίρεση της συντόμευσης από την άλλη εντολή και επιλογή της + Undo Changes Αναίρεση αλλαγών + {shortcut} is reserved by the system and can't be assigned. Η συντόμευση {shortcut} δεσμεύεται από το σύστημα και δεν μπορεί να εκχωρηθεί. diff --git a/crates/ui-egui/src/i18n/es.tsv b/crates/ui-egui/src/i18n/es.tsv index 2a38a4a93..350a5d74d 100644 --- a/crates/ui-egui/src/i18n/es.tsv +++ b/crates/ui-egui/src/i18n/es.tsv @@ -2837,3 +2837,10 @@ curves Smooth Suavizar There are too many sets: delete one first. Hay demasiados conjuntos: elimine uno primero. set name nombre del conjunto {set} (modified) {set} (modificado) + Accept and Go to Conflict Aceptar e ir al conflicto + Changes undone. Cambios deshechos. + Choose a new shortcut for this command, or leave it without one. Elija un nuevo método abreviado para este comando o déjelo sin ninguno. + Put this command's shortcuts back as they were Restaurar los métodos abreviados de este comando como estaban + Take the shortcut from the other command and select it Quitar el método abreviado al otro comando y seleccionarlo + Undo Changes Deshacer cambios + {shortcut} is reserved by the system and can't be assigned. {shortcut} está reservado por el sistema y no se puede asignar. diff --git a/crates/ui-egui/src/i18n/fr.tsv b/crates/ui-egui/src/i18n/fr.tsv index 9744243d9..efc84bf52 100644 --- a/crates/ui-egui/src/i18n/fr.tsv +++ b/crates/ui-egui/src/i18n/fr.tsv @@ -3154,3 +3154,10 @@ curves Smooth Lisser There are too many sets: delete one first. Il y a trop de jeux : supprimez-en un d’abord. set name nom du jeu {set} (modified) {set} (modifié) + Accept and Go to Conflict Accepter et aller au conflit + Changes undone. Modifications annulées. + Choose a new shortcut for this command, or leave it without one. Choisissez un nouveau raccourci pour cette commande ou laissez-la sans raccourci. + Put this command's shortcuts back as they were Rétablir les raccourcis de cette commande + Take the shortcut from the other command and select it Retirer le raccourci de l’autre commande et la sélectionner + Undo Changes Annuler les modifications + {shortcut} is reserved by the system and can't be assigned. {shortcut} est réservé par le système et ne peut pas être attribué. diff --git a/crates/ui-egui/src/i18n/hu.tsv b/crates/ui-egui/src/i18n/hu.tsv index c8126f6bd..9ed4c0bf7 100644 --- a/crates/ui-egui/src/i18n/hu.tsv +++ b/crates/ui-egui/src/i18n/hu.tsv @@ -4073,3 +4073,10 @@ cameraRaw Yellow Sárga There are too many sets: delete one first. Túl sok készlet van: előbb töröljön egyet. set name készlet neve {set} (modified) {set} (módosítva) + Accept and Go to Conflict Elfogadás és ugrás az ütközéshez + Changes undone. Változások visszavonva. + Choose a new shortcut for this command, or leave it without one. Válasszon új billentyűparancsot ehhez a parancshoz, vagy hagyja nélküle. + Put this command's shortcuts back as they were A parancs billentyűparancsainak visszaállítása + Take the shortcut from the other command and select it A billentyűparancs elvétele a másik parancstól, és annak kijelölése + Undo Changes Változások visszavonása + {shortcut} is reserved by the system and can't be assigned. A(z) {shortcut} a rendszer számára fenntartott, nem rendelhető hozzá. diff --git a/crates/ui-egui/src/i18n/id.tsv b/crates/ui-egui/src/i18n/id.tsv index 249c0603b..df6b8f857 100644 --- a/crates/ui-egui/src/i18n/id.tsv +++ b/crates/ui-egui/src/i18n/id.tsv @@ -3141,3 +3141,10 @@ curves Smooth Haluskan There are too many sets: delete one first. Terlalu banyak set: hapus satu terlebih dahulu. set name nama set {set} (modified) {set} (diubah) + Accept and Go to Conflict Terima dan Buka Konflik + Changes undone. Perubahan dibatalkan. + Choose a new shortcut for this command, or leave it without one. Pilih pintasan baru untuk perintah ini, atau biarkan tanpa pintasan. + Put this command's shortcuts back as they were Kembalikan pintasan perintah ini seperti semula + Take the shortcut from the other command and select it Ambil pintasan dari perintah lain dan pilih perintah itu + Undo Changes Batalkan Perubahan + {shortcut} is reserved by the system and can't be assigned. {shortcut} dicadangkan oleh sistem dan tidak dapat ditetapkan. diff --git a/crates/ui-egui/src/i18n/it.tsv b/crates/ui-egui/src/i18n/it.tsv index a3ebd8e02..b629308bb 100644 --- a/crates/ui-egui/src/i18n/it.tsv +++ b/crates/ui-egui/src/i18n/it.tsv @@ -4115,3 +4115,10 @@ navigator Zoom Zoom There are too many sets: delete one first. Ci sono troppi set: eliminane prima uno. set name nome del set {set} (modified) {set} (modificato) + Accept and Go to Conflict Accetta e vai al conflitto + Changes undone. Modifiche annullate. + Choose a new shortcut for this command, or leave it without one. Scegli una nuova scorciatoia per questo comando o lascialo senza. + Put this command's shortcuts back as they were Ripristina le scorciatoie di questo comando com'erano + Take the shortcut from the other command and select it Togli la scorciatoia all'altro comando e selezionalo + Undo Changes Annulla modifiche + {shortcut} is reserved by the system and can't be assigned. {shortcut} è riservata dal sistema e non può essere assegnata. diff --git a/crates/ui-egui/src/i18n/ja.tsv b/crates/ui-egui/src/i18n/ja.tsv index aab37e7a6..d4299018d 100644 --- a/crates/ui-egui/src/i18n/ja.tsv +++ b/crates/ui-egui/src/i18n/ja.tsv @@ -3830,3 +3830,10 @@ curves Smooth スムーズ There are too many sets: delete one first. セットが多すぎます。先に 1 つ削除してください。 set name セット名 {set} (modified) {set}(変更あり) + Accept and Go to Conflict 適用して競合へ移動 + Changes undone. 変更を取り消しました。 + Choose a new shortcut for this command, or leave it without one. このコマンドに新しいショートカットを選択するか、なしのままにしてください。 + Put this command's shortcuts back as they were このコマンドのショートカットを元に戻す + Take the shortcut from the other command and select it もう一方のコマンドからショートカットを外して選択 + Undo Changes 変更を取り消し + {shortcut} is reserved by the system and can't be assigned. {shortcut} はシステムで予約されているため割り当てられません。 diff --git a/crates/ui-egui/src/i18n/ko.tsv b/crates/ui-egui/src/i18n/ko.tsv index bf4b93867..3b61d6657 100644 --- a/crates/ui-egui/src/i18n/ko.tsv +++ b/crates/ui-egui/src/i18n/ko.tsv @@ -3327,3 +3327,10 @@ curves Smooth 매끄럽게 There are too many sets: delete one first. 세트가 너무 많습니다. 먼저 하나를 삭제하세요. set name 세트 이름 {set} (modified) {set}(수정됨) + Accept and Go to Conflict 적용 후 충돌 항목으로 이동 + Changes undone. 변경 사항을 취소했습니다. + Choose a new shortcut for this command, or leave it without one. 이 명령의 새 단축키를 선택하거나 단축키 없이 두세요. + Put this command's shortcuts back as they were 이 명령의 단축키를 원래대로 되돌리기 + Take the shortcut from the other command and select it 다른 명령에서 단축키를 빼고 그 명령 선택 + Undo Changes 변경 사항 취소 + {shortcut} is reserved by the system and can't be assigned. {shortcut}은(는) 시스템에서 예약되어 할당할 수 없습니다. diff --git a/crates/ui-egui/src/i18n/nl.tsv b/crates/ui-egui/src/i18n/nl.tsv index b13a28a7e..9c9d0cf27 100644 --- a/crates/ui-egui/src/i18n/nl.tsv +++ b/crates/ui-egui/src/i18n/nl.tsv @@ -3912,3 +3912,10 @@ curves Smooth Vloeiend maken There are too many sets: delete one first. Er zijn te veel sets: verwijder er eerst een. set name naam van de set {set} (modified) {set} (gewijzigd) + Accept and Go to Conflict Accepteren en naar conflict + Changes undone. Wijzigingen ongedaan gemaakt. + Choose a new shortcut for this command, or leave it without one. Kies een nieuwe sneltoets voor deze opdracht of laat hem zonder. + Put this command's shortcuts back as they were De sneltoetsen van deze opdracht herstellen + Take the shortcut from the other command and select it De sneltoets van de andere opdracht afnemen en die selecteren + Undo Changes Wijzigingen ongedaan maken + {shortcut} is reserved by the system and can't be assigned. {shortcut} is door het systeem gereserveerd en kan niet worden toegewezen. diff --git a/crates/ui-egui/src/i18n/pl.tsv b/crates/ui-egui/src/i18n/pl.tsv index e51e09484..a12a85102 100644 --- a/crates/ui-egui/src/i18n/pl.tsv +++ b/crates/ui-egui/src/i18n/pl.tsv @@ -3750,3 +3750,10 @@ curves Smooth Wygładź There are too many sets: delete one first. Zestawów jest za dużo: najpierw usuń jeden. set name nazwa zestawu {set} (modified) {set} (zmieniony) + Accept and Go to Conflict Akceptuj i przejdź do konfliktu + Changes undone. Zmiany cofnięte. + Choose a new shortcut for this command, or leave it without one. Wybierz nowy skrót dla tego polecenia lub zostaw je bez skrótu. + Put this command's shortcuts back as they were Przywróć skróty tego polecenia + Take the shortcut from the other command and select it Odbierz skrót drugiemu poleceniu i zaznacz je + Undo Changes Cofnij zmiany + {shortcut} is reserved by the system and can't be assigned. {shortcut} jest zarezerwowany przez system i nie można go przypisać. diff --git a/crates/ui-egui/src/i18n/pt-br.tsv b/crates/ui-egui/src/i18n/pt-br.tsv index 37391c9e7..48ff64a25 100644 --- a/crates/ui-egui/src/i18n/pt-br.tsv +++ b/crates/ui-egui/src/i18n/pt-br.tsv @@ -3942,3 +3942,10 @@ layerLabel No Color Sem cor There are too many sets: delete one first. Há conjuntos demais: exclua um primeiro. set name nome do conjunto {set} (modified) {set} (modificado) + Accept and Go to Conflict Aceitar e ir para o conflito + Changes undone. Alterações desfeitas. + Choose a new shortcut for this command, or leave it without one. Escolha um novo atalho para este comando ou deixe-o sem atalho. + Put this command's shortcuts back as they were Restaurar os atalhos deste comando como estavam + Take the shortcut from the other command and select it Tirar o atalho do outro comando e selecioná-lo + Undo Changes Desfazer alterações + {shortcut} is reserved by the system and can't be assigned. {shortcut} é reservado pelo sistema e não pode ser atribuído. diff --git a/crates/ui-egui/src/i18n/ru.tsv b/crates/ui-egui/src/i18n/ru.tsv index 7b62cc4c6..076bd4520 100644 --- a/crates/ui-egui/src/i18n/ru.tsv +++ b/crates/ui-egui/src/i18n/ru.tsv @@ -3118,3 +3118,10 @@ curves Smooth Сгладить There are too many sets: delete one first. Слишком много наборов: сначала удалите один. set name имя набора {set} (modified) {set} (изменён) + Accept and Go to Conflict Принять и перейти к конфликту + Changes undone. Изменения отменены. + Choose a new shortcut for this command, or leave it without one. Выберите новую комбинацию для этой команды или оставьте её без комбинации. + Put this command's shortcuts back as they were Вернуть комбинации этой команды + Take the shortcut from the other command and select it Снять комбинацию с другой команды и выбрать её + Undo Changes Отменить изменения + {shortcut} is reserved by the system and can't be assigned. Комбинация {shortcut} зарезервирована системой и не может быть назначена. diff --git a/crates/ui-egui/src/i18n/sr.tsv b/crates/ui-egui/src/i18n/sr.tsv index b00315d07..e6ae61fe8 100644 --- a/crates/ui-egui/src/i18n/sr.tsv +++ b/crates/ui-egui/src/i18n/sr.tsv @@ -4226,3 +4226,10 @@ shape Appearance Izgled There are too many sets: delete one first. Previše skupova: prvo obrišite jedan. set name ime skupa {set} (modified) {set} (izmenjen) + Accept and Go to Conflict Prihvati i idi na sukob + Changes undone. Izmene su poništene. + Choose a new shortcut for this command, or leave it without one. Izaberite novu prečicu za ovu komandu ili je ostavite bez prečice. + Put this command's shortcuts back as they were Vrati prečice ove komande kakve su bile + Take the shortcut from the other command and select it Uzmi prečicu drugoj komandi i izaberi je + Undo Changes Poništi izmene + {shortcut} is reserved by the system and can't be assigned. {shortcut} je rezervisana od strane sistema i ne može se dodeliti. diff --git a/crates/ui-egui/src/i18n/tr.tsv b/crates/ui-egui/src/i18n/tr.tsv index 00391e4d8..50a4164b8 100644 --- a/crates/ui-egui/src/i18n/tr.tsv +++ b/crates/ui-egui/src/i18n/tr.tsv @@ -3884,3 +3884,10 @@ cameraData Lens Lens There are too many sets: delete one first. Çok fazla küme var: önce birini silin. set name küme adı {set} (modified) {set} (değiştirildi) + Accept and Go to Conflict Kabul Et ve Çakışmaya Git + Changes undone. Değişiklikler geri alındı. + Choose a new shortcut for this command, or leave it without one. Bu komut için yeni bir kısayol seçin veya kısayolsuz bırakın. + Put this command's shortcuts back as they were Bu komutun kısayollarını eski haline getir + Take the shortcut from the other command and select it Kısayolu diğer komuttan al ve o komutu seç + Undo Changes Değişiklikleri Geri Al + {shortcut} is reserved by the system and can't be assigned. {shortcut} sistem tarafından ayrılmıştır ve atanamaz. diff --git a/crates/ui-egui/src/i18n/uk.tsv b/crates/ui-egui/src/i18n/uk.tsv index ca4cb337b..f157a709f 100644 --- a/crates/ui-egui/src/i18n/uk.tsv +++ b/crates/ui-egui/src/i18n/uk.tsv @@ -3851,3 +3851,10 @@ curves Smooth Згладити There are too many sets: delete one first. Забагато наборів: спершу видаліть один. set name назва набору {set} (modified) {set} (змінено) + Accept and Go to Conflict Прийняти й перейти до конфлікту + Changes undone. Зміни скасовано. + Choose a new shortcut for this command, or leave it without one. Виберіть нове клавіатурне скорочення для цієї команди або залиште її без нього. + Put this command's shortcuts back as they were Повернути клавіатурні скорочення цієї команди + Take the shortcut from the other command and select it Забрати скорочення в іншої команди й вибрати її + Undo Changes Скасувати зміни + {shortcut} is reserved by the system and can't be assigned. {shortcut} зарезервовано системою, його не можна призначити. diff --git a/crates/ui-egui/src/i18n/vi.tsv b/crates/ui-egui/src/i18n/vi.tsv index 6f8179051..8fcf8f420 100644 --- a/crates/ui-egui/src/i18n/vi.tsv +++ b/crates/ui-egui/src/i18n/vi.tsv @@ -3639,3 +3639,10 @@ curves Smooth Làm mượt There are too many sets: delete one first. Có quá nhiều bộ: hãy xóa một bộ trước. set name tên bộ {set} (modified) {set} (đã sửa đổi) + Accept and Go to Conflict Chấp nhận và đến xung đột + Changes undone. Đã hoàn tác thay đổi. + Choose a new shortcut for this command, or leave it without one. Chọn phím tắt mới cho lệnh này, hoặc để lệnh không có phím tắt. + Put this command's shortcuts back as they were Khôi phục phím tắt của lệnh này như cũ + Take the shortcut from the other command and select it Lấy phím tắt khỏi lệnh kia và chọn lệnh đó + Undo Changes Hoàn tác thay đổi + {shortcut} is reserved by the system and can't be assigned. {shortcut} được hệ thống dành riêng và không thể gán. diff --git a/crates/ui-egui/src/i18n/zh-hans.tsv b/crates/ui-egui/src/i18n/zh-hans.tsv index 131eb79ec..1de83b88f 100644 --- a/crates/ui-egui/src/i18n/zh-hans.tsv +++ b/crates/ui-egui/src/i18n/zh-hans.tsv @@ -2762,3 +2762,10 @@ curves Smooth 平滑 There are too many sets: delete one first. 组太多:请先删除一个。 set name 组名称 {set} (modified) {set}(已修改) + Accept and Go to Conflict 接受并转到冲突 + Changes undone. 已撤消更改。 + Choose a new shortcut for this command, or leave it without one. 为此命令选择新的快捷键,或保留为无快捷键。 + Put this command's shortcuts back as they were 将此命令的快捷键恢复原样 + Take the shortcut from the other command and select it 从另一个命令移除该快捷键并选中它 + Undo Changes 撤消更改 + {shortcut} is reserved by the system and can't be assigned. {shortcut} 由系统保留,无法指定。 diff --git a/crates/ui-egui/src/i18n/zh-hant.tsv b/crates/ui-egui/src/i18n/zh-hant.tsv index e070cf67d..dc6be3966 100644 --- a/crates/ui-egui/src/i18n/zh-hant.tsv +++ b/crates/ui-egui/src/i18n/zh-hant.tsv @@ -2747,3 +2747,10 @@ curves Smooth 平滑 There are too many sets: delete one first. 組合太多:請先刪除一個。 set name 組合名稱 {set} (modified) {set}(已修改) + Accept and Go to Conflict 接受並前往衝突 + Changes undone. 已還原變更。 + Choose a new shortcut for this command, or leave it without one. 為此指令選擇新的快速鍵,或保持沒有快速鍵。 + Put this command's shortcuts back as they were 將此指令的快速鍵恢復原狀 + Take the shortcut from the other command and select it 從另一個指令移除該快速鍵並選取它 + Undo Changes 還原變更 + {shortcut} is reserved by the system and can't be assigned. {shortcut} 由系統保留,無法指定。 diff --git a/crates/ui-egui/src/prefs_ui.rs b/crates/ui-egui/src/prefs_ui.rs index e63453243..2247e92d5 100644 --- a/crates/ui-egui/src/prefs_ui.rs +++ b/crates/ui-egui/src/prefs_ui.rs @@ -784,6 +784,19 @@ pub fn shortcut_items(app: &PhotocraftApp) -> Vec<(String, String, Vec, } /// Text of a key press for the shortcut editor (`Cmd+Shift+K`), `None` for bare modifiers. +/// Keys the system takes before the app sees them (switching apps, closing the window, force +/// quit): Edit › Keyboard Shortcuts won't assign them, as Photoshop won't. `sc` is in our +/// notation, where `Cmd` is Ctrl off the Mac. +pub fn reserved_shortcut(sc: &str) -> bool { + let Some(n) = prefs::normalize_shortcut(sc) else { return false }; + let reserved: &[&str] = if cfg!(target_os = "macos") { + &["Cmd+Tab", "Cmd+Shift+Tab", "Cmd+Alt+Escape", "Cmd+`"] + } else { + &["Alt+Tab", "Alt+Shift+Tab", "Alt+F4", "Cmd+Alt+Delete", "Cmd+Escape", "Cmd+Shift+Escape"] + }; + reserved.iter().filter_map(|r| prefs::normalize_shortcut(r)).any(|r| r == n) +} + pub fn shortcut_text(key: egui::Key, m: egui::Modifiers) -> Option { if is_modifier_key(key) { return None; @@ -1647,6 +1660,9 @@ fn shortcuts_body(app: &mut PhotocraftApp, ui: &mut egui::Ui, f: &mut Map = f.get("conflict").filter(|c| c.is_object()).cloned(); let mut hidden: Vec = f.get("hidden").and_then(|v| serde_json::from_value(v.clone()).ok()).unwrap_or_default(); let mut colors: BTreeMap = f.get("colors").and_then(|v| serde_json::from_value(v.clone()).ok()).unwrap_or_default(); let mut selected = f.get("selected").and_then(Value::as_str).unwrap_or("").to_string(); @@ -1708,8 +1724,12 @@ fn shortcuts_body(app: &mut PhotocraftApp, ui: &mut egui::Ui, f: &mut Map = items + let clash_ids: Vec<&str> = items .iter() .filter(|(id, _, _, def)| { let cur = eff(&overrides, id, def); @@ -1717,11 +1737,28 @@ fn shortcuts_body(app: &mut PhotocraftApp, ui: &mut egui::Ui, f: &mut Map = items + .iter() + .filter(|(id, ..)| clash_ids.contains(&id.as_str())) .map(|(id, label, path, _)| { let (path, label) = shown(id, label, path); format!("{} › {}", path.join(" › "), label.trim_end_matches('…')) }) .collect(); + // What Undo Changes puts back: the command's main key and further keys as they were. + if let Some(first) = clash_ids.first() { + conflict = Some(json!({ + "shortcut": sc, + "with": first, + "command": selected, + "main": overrides.get(&selected), + "alternates": alt_overrides.get(&selected), + })); + } else { + conflict = None; + } if capture_alt { let def = items.iter().find(|i| i.0 == selected).and_then(|i| i.3.clone()); let cur = eff(&overrides, &selected, &def); @@ -1883,6 +1920,44 @@ fn shortcuts_body(app: &mut PhotocraftApp, ui: &mut egui::Ui, f: &mut Map overrides.insert(command.to_string(), m.to_string()), + None => overrides.remove(command), + }; + match serde_json::from_value::>(c["alternates"].clone()) { + Ok(list) => alt_overrides.insert(command.to_string(), list), + Err(_) => alt_overrides.remove(command), + }; + selected = command.to_string(); + message = tl!("Changes undone.").into(); + message_warning = false; + conflict = None; + } + }); + } if overrides_ok { f.insert("overrides".into(), json!(overrides)); } @@ -1890,6 +1965,7 @@ fn shortcuts_body(app: &mut PhotocraftApp, ui: &mut egui::Ui, f: &mut Map = crate::shortcut_dispatch::bindings(&app).into_iter().filter(|(_, sc)| *sc == f7).map(|(id, _)| id).collect(); assert_eq!(bound, ["select.modify.feather"]); } + +/// Capture `k` with `m` for the selected command. +fn capture_key(h: &mut Harness<'_, PhotocraftApp>, id: u64, k: Key, m: Modifiers) { + h.state_mut().ui.dialog_mut(id).unwrap().fields.insert("capture".into(), json!(true)); + h.run_steps(2); + key(h, k, true, m); + h.run_steps(2); + key(h, k, false, m); + h.run_steps(2); +} + +fn click(h: &mut Harness<'_, PhotocraftApp>, label: &str) { + h.get_by_role_and_label(egui::accesskit::Role::Button, label).click(); + h.run_steps(3); +} + +#[test] +fn a_conflict_offers_accept_and_go_to_conflict() { + // Photoshop: the key is taken from Copy now, and Copy is selected to get a new one. + let (mut h, id) = dialog(1.0, "edit.cut", ""); + capture_key(&mut h, id, Key::C, Modifiers::COMMAND); + assert_eq!(field(&h, id, "overrides")["edit.cut"], json!("Cmd+C")); + assert_eq!(field(&h, id, "conflict")["with"], json!("edit.copy")); + click(&mut h, "Accept and Go to Conflict"); + assert_eq!(field(&h, id, "selected"), json!("edit.copy")); + assert_eq!(field(&h, id, "overrides")["edit.copy"], json!(""), "Copy no longer holds Cmd+C"); + assert!(field(&h, id, "conflict").is_null()); + crate::dialogs::confirm(h.state_mut(), id).unwrap(); + assert_eq!(crate::shortcuts::effective_shortcut(h.state(), "edit.cut", Some("Cmd+X")).as_deref(), Some("Cmd+C")); + assert_eq!(crate::shortcuts::effective_shortcut(h.state(), "edit.copy", Some("Cmd+C")), None); +} + +#[test] +fn undo_changes_puts_the_command_back() { + let (mut h, id) = dialog(1.0, "edit.cut", ""); + capture_key(&mut h, id, Key::C, Modifiers::COMMAND); + click(&mut h, "Undo Changes"); + assert!(field(&h, id, "overrides").get("edit.cut").is_none(), "{}", field(&h, id, "overrides")); + assert!(field(&h, id, "conflict").is_null()); + // An alternate added with Add Shortcut is undone the same way. + h.state_mut().ui.dialog_mut(id).unwrap().fields.insert("captureAlt".into(), json!(true)); + capture_key(&mut h, id, Key::C, Modifiers::COMMAND); + assert_eq!(field(&h, id, "alternates")["edit.cut"], json!(["F2", "Cmd+C"]), "beside Photoshop's F2"); + click(&mut h, "Undo Changes"); + assert!(field(&h, id, "alternates").get("edit.cut").is_none(), "{}", field(&h, id, "alternates")); + crate::dialogs::confirm(h.state_mut(), id).unwrap(); + assert_eq!(crate::shortcuts::effective_shortcut(h.state(), "edit.copy", Some("Cmd+C")).as_deref(), Some("Cmd+C")); +} + +#[test] +fn a_system_key_is_refused() { + let (k, m) = if cfg!(target_os = "macos") { (Key::Tab, Modifiers::MAC_CMD | Modifiers::COMMAND) } else { (Key::F4, Modifiers::ALT) }; + let (mut h, id) = dialog(1.0, "edit.cut", ""); + capture_key(&mut h, id, k, m); + assert!(field(&h, id, "overrides").get("edit.cut").is_none(), "{}", field(&h, id, "overrides")); + assert!(field(&h, id, "message").as_str().is_some_and(|s| s.contains("reserved")), "{}", field(&h, id, "message")); + assert_eq!(field(&h, id, "messageWarning"), json!(true)); + assert!(crate::prefs_ui::reserved_shortcut(if cfg!(target_os = "macos") { "Cmd+Tab" } else { "Alt+F4" })); + assert!(!crate::prefs_ui::reserved_shortcut("Cmd+Shift+F4")); + assert!(!crate::prefs_ui::reserved_shortcut("garbage+")); +}