mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-09 09:29:44 -06:00
Actions: the panel menu's Duplicate copies the selected action or set
The Actions panel menu has Duplicate, between New Set… and Delete. With
an action selected it copies that action to right after it in the same
set; otherwise it copies the current set, with all its actions, to right
after that set. The copy is named after the original with " copy" added
and is selected, and a copied set gets an id of its own. Copies are
saved with the other sets.
ui.actionSet.duplicate {set?: index, action?: index} does the copy and
returns {set, action?}. An index past the last set or action is an
error. A recording into a later set and an open Set Options or Batch
dialog stay on their own set and action.
This commit is contained in:
@@ -747,6 +747,7 @@ font-technology Variable Променливи
|
||||
Delete Tab Изтриване на табулация
|
||||
Delete the graphic style “{name}”? Изтриване на графичния стил „{name}“?
|
||||
Delete Action Sets Изтриване на набори от действия
|
||||
Duplicate Action or Action Set Дублиране на действие или набор от действия
|
||||
Delete the action set “{name}” and its actions? Изтриване на набора от действия „{name}“ и неговите действия?
|
||||
Delete the selected action sets and their actions? Изтриване на избраните набори от действия и техните действия?
|
||||
Delete Theme Изтриване на тема
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -1553,6 +1553,7 @@ digits Malayalam Malajalam
|
||||
Delete Graphic Style (Alt-click: without asking) Izbriši grafički stil (Alt-klik: bez pitanja)
|
||||
Delete the graphic style “{name}”? Izbrisati grafički stil „{name}”?
|
||||
Delete Action Sets Izbriši skupove akcija
|
||||
Duplicate Action or Action Set Dupliciraj akciju ili skup akcija
|
||||
Delete the action set “{name}” and its actions? Izbrisati skup akcija „{name}” i njegove akcije?
|
||||
Delete the selected action sets and their actions? Izbrisati odabrane skupove akcija i njihove akcije?
|
||||
Delete these {n} graphic styles? Izbrisati ove grafičke stilove ({n})?
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -1064,6 +1064,7 @@
|
||||
Delete Tab Suprimeix la tabulació
|
||||
Delete the graphic style “{name}”? Voleu suprimir l’estil gràfic “{name}”?
|
||||
Delete Action Sets Suprimeix els conjunts d’accions
|
||||
Duplicate Action or Action Set Duplica l’acció o el conjunt d’accions
|
||||
Delete the action set “{name}” and its actions? Voleu suprimir el conjunt d’accions “{name}” i les seves accions?
|
||||
Delete the selected action sets and their actions? Voleu suprimir els conjunts d’accions seleccionats i les seves accions?
|
||||
Delete the library “{name}”? Voleu suprimir la biblioteca “{name}”?
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -1577,6 +1577,7 @@ digits Malayalam Malajálamské
|
||||
Delete Graphic Style (Alt-click: without asking) Odstranit grafický styl (Alt+kliknutí: bez dotazu)
|
||||
Delete the graphic style “{name}”? Odstranit grafický styl „{name}“?
|
||||
Delete Action Sets Odstranit sady akcí
|
||||
Duplicate Action or Action Set Duplikovat akci nebo sadu akcí
|
||||
Delete the action set “{name}” and its actions? Odstranit sadu akcí „{name}“ a její akce?
|
||||
Delete the selected action sets and their actions? Odstranit vybrané sady akcí a jejich akce?
|
||||
Delete these {n} graphic styles? Odstranit tyto grafické styly ({n})?
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -1487,6 +1487,7 @@ digits Malayalam Malayalam
|
||||
Delete Graphic Style (Alt-click: without asking) Slet grafisk typografi (Alt-klik: uden at spørge)
|
||||
Delete the graphic style “{name}”? Slet den grafiske typografi »{name}«?
|
||||
Delete Action Sets Slet handlingssæt
|
||||
Duplicate Action or Action Set Duplikér handling eller handlingssæt
|
||||
Delete the action set “{name}” and its actions? Slet handlingssættet »{name}« og dets handlinger?
|
||||
Delete the selected action sets and their actions? Slet de markerede handlingssæt og deres handlinger?
|
||||
Delete these {n} graphic styles? Slet disse {n} grafiske typografier?
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -741,6 +741,7 @@ font-technology Variable Variabel
|
||||
Delete Tab Tabulator löschen
|
||||
Delete the graphic style “{name}”? Grafikstil „{name}“ löschen?
|
||||
Delete Action Sets Aktionssätze löschen
|
||||
Duplicate Action or Action Set Aktion oder Aktionssatz duplizieren
|
||||
Delete the action set “{name}” and its actions? Aktionssatz „{name}“ und seine Aktionen löschen?
|
||||
Delete the selected action sets and their actions? Ausgewählte Aktionssätze und ihre Aktionen löschen?
|
||||
Delete Theme Thema löschen
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -721,6 +721,7 @@ font-technology Variable Μεταβλητές
|
||||
Delete Tab Διαγραφή στηλοθέτη
|
||||
Delete the graphic style “{name}”? Να διαγραφεί το στυλ γραφικών «{name}»;
|
||||
Delete Action Sets Διαγραφή συνόλων ενεργειών
|
||||
Duplicate Action or Action Set Δημιουργία αντιγράφου ενέργειας ή συνόλου ενεργειών
|
||||
Delete the action set “{name}” and its actions? Να διαγραφεί το σύνολο ενεργειών «{name}» και οι ενέργειές του;
|
||||
Delete the selected action sets and their actions? Να διαγραφούν τα επιλεγμένα σύνολα ενεργειών και οι ενέργειές τους;
|
||||
Delete Theme Διαγραφή θέματος
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 164 and column 5.
|
@@ -762,6 +762,7 @@ font-technology Variable Variables
|
||||
Delete Tab Eliminar tabulación
|
||||
Delete the graphic style “{name}”? ¿Eliminar el estilo gráfico “{name}”?
|
||||
Delete Action Sets Eliminar conjuntos de acciones
|
||||
Duplicate Action or Action Set Duplicar acción o conjunto de acciones
|
||||
Delete the action set “{name}” and its actions? ¿Eliminar el conjunto de acciones “{name}” y sus acciones?
|
||||
Delete the selected action sets and their actions? ¿Eliminar los conjuntos de acciones seleccionados y sus acciones?
|
||||
Delete Theme Eliminar tema
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -1550,6 +1550,7 @@ digits Malayalam Malajalam
|
||||
Delete Graphic Style (Alt-click: without asking) Poista grafiikkatyyli (Alt-napsautus: kysymättä)
|
||||
Delete the graphic style “{name}”? Poistetaanko grafiikkatyyli ”{name}”?
|
||||
Delete Action Sets Poista toimintosarjat
|
||||
Duplicate Action or Action Set Monista toiminto tai toimintosarja
|
||||
Delete the action set “{name}” and its actions? Poistetaanko toimintosarja ”{name}” ja sen toiminnot?
|
||||
Delete the selected action sets and their actions? Poistetaanko valitut toimintosarjat ja niiden toiminnot?
|
||||
Delete these {n} graphic styles? Poistetaanko nämä {n} grafiikkatyyliä?
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -748,6 +748,7 @@ font-technology Variable Variables
|
||||
Delete Selected Item Supprimer l’élément sélectionné
|
||||
Delete Selection Supprimer la sélection
|
||||
Delete Action Sets Supprimer les jeux de scripts
|
||||
Duplicate Action or Action Set Dupliquer le script ou le jeu de scripts
|
||||
Delete the action set “{name}” and its actions? Supprimer le jeu de scripts « {name} » et ses scripts ?
|
||||
Delete the selected action sets and their actions? Supprimer les jeux de scripts sélectionnés et leurs scripts ?
|
||||
Delete Slices Supprimer les tranches
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -986,6 +986,7 @@ font-technology Variable Változó
|
||||
Delete Tab Tabulátor törlése
|
||||
Delete the graphic style “{name}”? Törlöd ezt a grafikai stílust: „{name}”?
|
||||
Delete Action Sets Műveletkészletek törlése
|
||||
Duplicate Action or Action Set Művelet vagy műveletkészlet kettőzése
|
||||
Delete the action set “{name}” and its actions? Törlöd ezt a műveletkészletet és a műveleteit: „{name}”?
|
||||
Delete the selected action sets and their actions? Törlöd a kijelölt műveletkészleteket és a műveleteiket?
|
||||
Delete the library “{name}”? Törlöd ezt a könyvtárat: „{name}”?
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -1487,6 +1487,7 @@ digits Malayalam Malayalam
|
||||
Delete Graphic Style (Alt-click: without asking) Hapus gaya grafis (Alt+klik: tanpa konfirmasi)
|
||||
Delete the graphic style “{name}”? Hapus gaya grafis “{name}”?
|
||||
Delete Action Sets Hapus set tindakan
|
||||
Duplicate Action or Action Set Duplikatkan tindakan atau set tindakan
|
||||
Delete the action set “{name}” and its actions? Hapus set tindakan “{name}” beserta tindakannya?
|
||||
Delete the selected action sets and their actions? Hapus set tindakan yang dipilih beserta tindakannya?
|
||||
Delete these {n} graphic styles? Hapus {n} gaya grafis ini?
|
||||
|
||||
|
@@ -762,6 +762,7 @@ font-technology Variable Variabili
|
||||
Delete Tab Elimina tabulazione
|
||||
Delete the graphic style “{name}”? Eliminare lo stile grafico “{name}”?
|
||||
Delete Action Sets Elimina set di azioni
|
||||
Duplicate Action or Action Set Duplica azione o set di azioni
|
||||
Delete the action set “{name}” and its actions? Eliminare il set di azioni “{name}” e le sue azioni?
|
||||
Delete the selected action sets and their actions? Eliminare i set di azioni selezionati e le loro azioni?
|
||||
Delete Theme Elimina tema
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -1333,6 +1333,7 @@ digits Malayalam マラヤーラム数字
|
||||
Delete Workspace ワークスペースを削除
|
||||
Delete the graphic style “{name}”? グラフィックスタイル「{name}」を削除しますか?
|
||||
Delete Action Sets アクションセットを削除
|
||||
Duplicate Action or Action Set アクションまたはアクションセットを複製
|
||||
Delete the action set “{name}” and its actions? アクションセット「{name}」とそのアクションを削除しますか?
|
||||
Delete the selected action sets and their actions? 選択したアクションセットとそのアクションを削除しますか?
|
||||
Delete theme テーマを削除
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -1404,6 +1404,7 @@ digits Malayalam მალაიალამური
|
||||
Delete Graphic Style (Alt-click: without asking) გრაფიკული სტილის წაშლა (Alt-დაწკაპუნებით: დაუკითხავად)
|
||||
Delete the graphic style “{name}”? წაიშალოს გრაფიკული სტილი „{name}“?
|
||||
Delete Action Sets მოქმედებების ნაკრებების წაშლა
|
||||
Duplicate Action or Action Set მოქმედების ან მოქმედებების ნაკრების დუბლირება
|
||||
Delete the action set “{name}” and its actions? წაიშალოს მოქმედებების ნაკრები „{name}“ და მისი მოქმედებები?
|
||||
Delete the selected action sets and their actions? წაიშალოს მონიშნული მოქმედებების ნაკრებები და მათი მოქმედებები?
|
||||
Delete these {n} graphic styles? წაიშალოს ეს გრაფიკული სტილები ({n})?
|
||||
|
||||
|
Can't render this file because it is too large.
|
@@ -1323,6 +1323,7 @@ digits Malayalam 말라얄람어
|
||||
Delete Workspace 작업 영역 삭제
|
||||
Delete the graphic style “{name}”? 그래픽 스타일 “{name}”을(를) 삭제하시겠습니까?
|
||||
Delete Action Sets 액션 세트 삭제
|
||||
Duplicate Action or Action Set 액션 또는 액션 세트 복제
|
||||
Delete the action set “{name}” and its actions? 액션 세트 “{name}”과(와) 해당 액션을 삭제하시겠습니까?
|
||||
Delete the selected action sets and their actions? 선택한 액션 세트와 해당 액션을 삭제하시겠습니까?
|
||||
Delete theme 테마 삭제
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -1501,6 +1501,7 @@ digits Malayalam Malayalam
|
||||
Delete Graphic Style (Alt-click: without asking) Grafische stijl verwijderen (Alt-klik: zonder vragen)
|
||||
Delete the graphic style “{name}”? De grafische stijl „{name}” verwijderen?
|
||||
Delete Action Sets Actiesets verwijderen
|
||||
Duplicate Action or Action Set Actie of actieset dupliceren
|
||||
Delete the action set “{name}” and its actions? De actieset „{name}” en de acties erin verwijderen?
|
||||
Delete the selected action sets and their actions? De geselecteerde actiesets en de acties erin verwijderen?
|
||||
Delete these {n} graphic styles? Deze {n} grafische stijlen verwijderen?
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -1490,6 +1490,7 @@ digits Malayalam Malajalam
|
||||
Delete Graphic Style (Alt-click: without asking) Usuń styl graficzny (kliknięcie z Alt: bez pytania)
|
||||
Delete the graphic style “{name}”? Usunąć styl graficzny „{name}”?
|
||||
Delete Action Sets Usuń zestawy operacji
|
||||
Duplicate Action or Action Set Powiel operację lub zestaw operacji
|
||||
Delete the action set “{name}” and its actions? Usunąć zestaw operacji „{name}” i jego operacje?
|
||||
Delete the selected action sets and their actions? Usunąć zaznaczone zestawy operacji i ich operacje?
|
||||
Delete these {n} graphic styles? Usunąć te style graficzne ({n})?
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -679,6 +679,7 @@
|
||||
Delete Workspace Excluir Espaço de Trabalho
|
||||
Delete the graphic style “{name}”? Excluir o estilo gráfico “{name}”?
|
||||
Delete Action Sets Excluir Conjuntos de Ações
|
||||
Duplicate Action or Action Set Duplicar Ação ou Conjunto de Ações
|
||||
Delete the action set “{name}” and its actions? Excluir o conjunto de ações “{name}” e suas ações?
|
||||
Delete the selected action sets and their actions? Excluir os conjuntos de ações selecionados e suas ações?
|
||||
Delete theme Excluir tema
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 6 and column 47.
|
@@ -760,6 +760,7 @@ font-technology Variable Вариативные
|
||||
Delete Tab Удалить табуляцию
|
||||
Delete the graphic style “{name}”? Удалить графический стиль «{name}»?
|
||||
Delete Action Sets Удалить наборы действий
|
||||
Duplicate Action or Action Set Дублировать действие или набор действий
|
||||
Delete the action set “{name}” and its actions? Удалить набор действий «{name}» и его действия?
|
||||
Delete the selected action sets and their actions? Удалить выбранные наборы действий и их действия?
|
||||
Delete Theme Удалить тему
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -749,6 +749,7 @@ font-technology Variable Variabla
|
||||
Delete Tab Radera tabb
|
||||
Delete the graphic style “{name}”? Radera grafikstilen ”{name}”?
|
||||
Delete Action Sets Radera åtgärdsuppsättningar
|
||||
Duplicate Action or Action Set Duplicera åtgärd eller åtgärdsuppsättning
|
||||
Delete the action set “{name}” and its actions? Radera åtgärdsuppsättningen ”{name}” och dess åtgärder?
|
||||
Delete the selected action sets and their actions? Radera de markerade åtgärdsuppsättningarna och deras åtgärder?
|
||||
Delete Theme Radera tema
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 5 and column 25.
|
@@ -741,6 +741,7 @@ font-technology Variable Değişken
|
||||
Delete Tab Sekmeyi Sil
|
||||
Delete the graphic style “{name}”? “{name}” grafik stili silinsin mi?
|
||||
Delete Action Sets Eylem Setlerini Sil
|
||||
Duplicate Action or Action Set Eylemi veya Eylem Setini Çoğalt
|
||||
Delete the action set “{name}” and its actions? “{name}” eylem seti ve eylemleri silinsin mi?
|
||||
Delete the selected action sets and their actions? Seçili eylem setleri ve eylemleri silinsin mi?
|
||||
Delete Theme Temayı Sil
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 5 and column 25.
|
@@ -756,6 +756,7 @@ font-technology Variable Варіативні
|
||||
Delete Tab Видалити табуляцію
|
||||
Delete the graphic style “{name}”? Видалити графічний стиль «{name}»?
|
||||
Delete Action Sets Видалити набори дій
|
||||
Duplicate Action or Action Set Дублювати дію або набір дій
|
||||
Delete the action set “{name}” and its actions? Видалити набір дій «{name}» і його дії?
|
||||
Delete the selected action sets and their actions? Видалити вибрані набори дій і їхні дії?
|
||||
Delete Theme Видалити тему
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 178 and column 5.
|
@@ -882,6 +882,7 @@ font-technology Variable Biến thiên
|
||||
Delete Tab Xóa tab
|
||||
Delete the graphic style “{name}”? Xóa kiểu đồ họa “{name}”?
|
||||
Delete Action Sets Xóa các bộ hành động
|
||||
Duplicate Action or Action Set Nhân bản hành động hoặc bộ hành động
|
||||
Delete the action set “{name}” and its actions? Xóa bộ hành động “{name}” và các hành động của nó?
|
||||
Delete the selected action sets and their actions? Xóa các bộ hành động đã chọn và các hành động của chúng?
|
||||
Delete the library “{name}”? Xóa thư viện “{name}”?
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 200 and column 5.
|
@@ -705,6 +705,7 @@
|
||||
Delete Tab 删除制表位
|
||||
Delete the graphic style “{name}”? 要删除图形样式“{name}”吗?
|
||||
Delete Action Sets 删除动作组
|
||||
Duplicate Action or Action Set 复制动作或动作组
|
||||
Delete the action set “{name}” and its actions? 要删除动作组“{name}”及其中的动作吗?
|
||||
Delete the selected action sets and their actions? 要删除所选动作组及其中的动作吗?
|
||||
Delete Theme 删除主题
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -724,6 +724,7 @@ font-technology Variable 可變
|
||||
Delete Tab 刪除定位點
|
||||
Delete the graphic style “{name}”? 要刪除繪圖樣式「{name}」嗎?
|
||||
Delete Action Sets 刪除動作組
|
||||
Duplicate Action or Action Set 製作動作或動作組複本
|
||||
Delete the action set “{name}” and its actions? 要刪除動作組「{name}」及其中的動作嗎?
|
||||
Delete the selected action sets and their actions? 要刪除所選動作組及其中的動作嗎?
|
||||
Delete Theme 刪除主題
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 6 and column 47.
|
@@ -789,6 +789,7 @@ fn run_ui_part11(app: &mut VectorcraftApp, id: &str, p: &Value) -> Option<Result
|
||||
crate::dialogs::action_batch::open(app, set, action)
|
||||
}
|
||||
crate::panels::actions::DELETE_SETS => crate::panels::actions::delete_sets(app, p),
|
||||
crate::panels::actions::DUPLICATE => crate::panels::actions::duplicate(app, p),
|
||||
"ui.shortcutImportDialog" => crate::dialogs::shortcut_import::command(app, p),
|
||||
_ => return None,
|
||||
};
|
||||
|
||||
@@ -1125,6 +1125,12 @@ pub const UI_COMMANDS: &[(&str, &str, &str, &str)] = &[
|
||||
"",
|
||||
"{sets?: [index], ids?: [id]} delete the Actions panel's sets at these indexes (0 is the top set), with their actions (default: the current set). ids holds the panel's own set ids, which its question passes: the sets with these ids are deleted wherever they are now, sets is not read, and when one of them no longer exists nothing is deleted. The panel's Delete Selection on selected sets (Shift-click adds a range) asks first, and OK runs this. A recording into a deleted set stops and keeps nothing. An index past the last set is an error → {deleted: n}",
|
||||
),
|
||||
(
|
||||
crate::panels::actions::DUPLICATE,
|
||||
"Duplicate Action or Action Set",
|
||||
"",
|
||||
"{set?: index, action?: index} copy the Actions panel's action at action in set (0 is the top set) to right after it in the same set; without action, copy set with all its actions to right after it (default: the current set). The copy is named after the original with \" copy\" added, a copied set gets an id of its own, and the copy is selected. The panel menu's Duplicate runs this for the selected action, else the current set. An index past the last set or action is an error → {set, action?}",
|
||||
),
|
||||
("file.showPackage", "Show Package", "", "{folder} show a package folder (file.package's folder) in the file manager → {folder}"),
|
||||
(
|
||||
"docInfo.save",
|
||||
|
||||
@@ -146,9 +146,6 @@ pub fn delete_sets(app: &mut VectorcraftApp, p: &Value) -> Result<Value, String>
|
||||
}
|
||||
// An open Set Options or Batch dialog holds a set index: it closes when its set is deleted,
|
||||
// and otherwise follows its set down.
|
||||
let holds_set = |d: &crate::state::Dialog| {
|
||||
d.kind == crate::dialogs::action_batch::KIND || (d.kind == crate::dialogs::action_set_options::KIND && d.fields.contains_key("set"))
|
||||
};
|
||||
if let Some(d) = app.ui.dialog.as_mut().filter(|d| holds_set(d))
|
||||
&& let Some(set) = d.fields.get("set").and_then(Value::as_u64).and_then(|s| usize::try_from(s).ok())
|
||||
{
|
||||
@@ -168,6 +165,88 @@ pub fn delete_sets(app: &mut VectorcraftApp, p: &Value) -> Result<Value, String>
|
||||
Ok(json!({ "deleted": sets.len() }))
|
||||
}
|
||||
|
||||
/// Whether dialog `d` is a Set Options or Batch dialog that holds a set index in its `set` field.
|
||||
fn holds_set(d: &crate::state::Dialog) -> bool {
|
||||
d.kind == crate::dialogs::action_batch::KIND || (d.kind == crate::dialogs::action_set_options::KIND && d.fields.contains_key("set"))
|
||||
}
|
||||
|
||||
/// The command that duplicates an action or an action set ([`duplicate`]).
|
||||
pub const DUPLICATE: &str = "ui.actionSet.duplicate";
|
||||
|
||||
/// The panel menu's Duplicate: copies the selected action, else the current set ([`DUPLICATE`]),
|
||||
/// and selects the copy.
|
||||
fn duplicate_selection(app: &mut VectorcraftApp, ctx: &egui::Context) {
|
||||
const SELECTED: &str = "actions-selected";
|
||||
let Some(set) = app.ui.action_set.filter(|&s| s < app.ui.action_sets.len()) else { return };
|
||||
// A selected action counts only while its set is the current one, as the panel shows it.
|
||||
let params = match pstate::<Option<(usize, usize)>>(ctx, SELECTED).filter(|&(s, _)| s == set) {
|
||||
Some((s, a)) => json!({ "set": s, "action": a }),
|
||||
None => json!({ "set": set }),
|
||||
};
|
||||
match app.run(DUPLICATE, params) {
|
||||
Ok(r) => {
|
||||
let copy = r["set"].as_u64().zip(r["action"].as_u64()).and_then(|(s, a)| Some((usize::try_from(s).ok()?, usize::try_from(a).ok()?)));
|
||||
set_pstate::<Option<(usize, usize)>>(ctx, SELECTED, copy);
|
||||
}
|
||||
Err(e) => app.status(e),
|
||||
}
|
||||
}
|
||||
|
||||
/// `ui.actionSet.duplicate {set?: index, action?: index}`: copies the action at index `action`
|
||||
/// of set `set` into the same set, right after the original; without `action`, copies set `set`
|
||||
/// with all its actions to right after the original set (default: the current set). The copy is
|
||||
/// named after the original with " copy" added, and a copied set gets an id of its own
|
||||
/// ([`ActionSet::id`]). The copy is selected and its set is the current one. A recording and an
|
||||
/// open Set Options or Batch dialog keep to their own set and action. → {set, action?}
|
||||
pub fn duplicate(app: &mut VectorcraftApp, p: &Value) -> Result<Value, String> {
|
||||
const SELECTED: &str = "actions-selected";
|
||||
let len = app.ui.action_sets.len();
|
||||
let index = |v: &Value| v.as_u64().and_then(|i| usize::try_from(i).ok());
|
||||
let set = match p.get("set") {
|
||||
None | Some(Value::Null) => app.ui.action_set.filter(|&s| s < len).ok_or("no action set is current")?,
|
||||
Some(v) => index(v).filter(|&s| s < len).ok_or("no such action set")?,
|
||||
};
|
||||
let Some(src) = app.ui.action_sets.get_mut(set) else { return Err("no such action set".into()) };
|
||||
let action = match p.get("action") {
|
||||
None | Some(Value::Null) => None,
|
||||
Some(v) => Some(index(v).filter(|&a| a < src.actions.len()).ok_or("no such action")?),
|
||||
};
|
||||
let (copy, result) = if let Some(a) = action {
|
||||
let Some(mut copy) = src.actions.get(a).cloned() else { return Err("no such action".into()) };
|
||||
copy.name = format!("{} copy", copy.name);
|
||||
src.actions.insert(a + 1, copy);
|
||||
// A Batch dialog open on a later action of the set follows it down.
|
||||
if let Some(d) = app.ui.dialog.as_mut().filter(|d| d.kind == crate::dialogs::action_batch::KIND)
|
||||
&& d.fields.get("set").and_then(index) == Some(set)
|
||||
&& let Some(da) = d.fields.get("action").and_then(index).filter(|&da| da > a)
|
||||
{
|
||||
d.fields.insert("action".into(), json!(da + 1));
|
||||
}
|
||||
(Some((set, a + 1)), json!({ "set": set, "action": a + 1 }))
|
||||
} else {
|
||||
let copy = ActionSet::new(format!("{} copy", src.name), src.actions.clone());
|
||||
app.ui.action_sets.insert(set + 1, copy);
|
||||
if let Some((rec, ..)) = app.ui.recording.as_mut()
|
||||
&& *rec > set
|
||||
{
|
||||
*rec += 1;
|
||||
}
|
||||
if let Some(d) = app.ui.dialog.as_mut().filter(|d| holds_set(d))
|
||||
&& let Some(ds) = d.fields.get("set").and_then(index).filter(|&ds| ds > set)
|
||||
{
|
||||
d.fields.insert("set".into(), json!(ds + 1));
|
||||
}
|
||||
(None, json!({ "set": set + 1 }))
|
||||
};
|
||||
let current = copy.map_or(set + 1, |(s, _)| s);
|
||||
app.ui.action_set = Some(current);
|
||||
app.ui.action_sets_selected = vec![current];
|
||||
if let Some(ctx) = app.ui_ctx.clone() {
|
||||
set_pstate::<Option<(usize, usize)>>(&ctx, SELECTED, copy);
|
||||
}
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
/// The panel's (≡) menu.
|
||||
pub fn menu(app: &mut VectorcraftApp, ui: &mut egui::Ui) {
|
||||
let selected: Option<(usize, usize)> = pstate(ui.ctx(), "actions-selected");
|
||||
@@ -175,10 +254,13 @@ pub fn menu(app: &mut VectorcraftApp, ui: &mut egui::Ui) {
|
||||
if widgets::menu_item(ui, tl!("New Set…"), true, false) {
|
||||
crate::dialogs::action_set_options::open_new(app);
|
||||
}
|
||||
let current = app.ui.action_set.filter(|&s| s < app.ui.action_sets.len());
|
||||
if widgets::menu_item(ui, tl!("Duplicate"), current.is_some(), false) {
|
||||
duplicate_selection(app, ui.ctx());
|
||||
}
|
||||
if widgets::menu_item(ui, tl!("Delete"), has || !selected_sets(app).is_empty(), false) {
|
||||
delete_selection(app, ui.ctx());
|
||||
}
|
||||
let current = app.ui.action_set.filter(|&s| s < app.ui.action_sets.len());
|
||||
if widgets::menu_item(ui, tl!("Set Options…"), current.is_some(), false)
|
||||
&& let Some(s) = current
|
||||
{
|
||||
@@ -734,6 +816,97 @@ mod tests {
|
||||
assert_eq!((d.fields["set"].clone(), d.fields["action"].clone()), (json!(0), json!(1)), "it follows Mine to index 0");
|
||||
}
|
||||
|
||||
/// A click on the panel menu's Duplicate.
|
||||
fn menu_duplicate(ctx: &egui::Context, app: &mut VectorcraftApp) {
|
||||
use super::super::tests_appearance::{click, frame_events};
|
||||
let texts = frame_events(ctx, app, vec![], menu);
|
||||
let item = texts.iter().find(|(s, _)| s.trim() == "Duplicate").map(|(_, r)| *r).expect("Duplicate in the menu");
|
||||
click(ctx, app, item.center(), menu);
|
||||
}
|
||||
|
||||
fn action_names(app: &VectorcraftApp, set: usize) -> Vec<String> {
|
||||
app.ui.action_sets[set].actions.iter().map(|a| a.name.clone()).collect()
|
||||
}
|
||||
|
||||
/// The panel menu's Duplicate copies the selected action to right after it in its set, named
|
||||
/// with " copy" added and with steps of its own, and selects the copy.
|
||||
#[test]
|
||||
fn the_panel_menus_duplicate_copies_the_selected_action() {
|
||||
use super::super::tests_appearance::{click, frame_events, text_rect};
|
||||
let mut app = app_with_sets();
|
||||
let ctx = egui::Context::default();
|
||||
let texts = frame_events(&ctx, &mut app, vec![], show);
|
||||
click(&ctx, &mut app, text_rect(&texts, "Nudge").center(), show);
|
||||
frame_events(&ctx, &mut app, vec![], show);
|
||||
menu_duplicate(&ctx, &mut app);
|
||||
assert_eq!(action_names(&app, 1), ["Nudge", "Nudge copy", "Nudge Again"], "the copy goes right after the original");
|
||||
assert_eq!(set_names(&app), ["Default Actions", "Mine", "Other"], "no set is added");
|
||||
assert_eq!(app.ui.action_sets[1].actions[1].steps, app.ui.action_sets[1].actions[0].steps);
|
||||
assert_eq!(pstate::<Option<(usize, usize)>>(&ctx, "actions-selected"), Some((1, 1)), "the copy is selected");
|
||||
frame_events(&ctx, &mut app, vec![], show);
|
||||
assert_eq!(pstate::<Option<(usize, usize)>>(&ctx, "actions-selected"), Some((1, 1)), "and stays selected in the panel");
|
||||
app.ui.action_sets[1].actions[1].steps[0].1 = json!({"dx": 5, "dy": 0});
|
||||
assert_eq!(app.ui.action_sets[1].actions[0].steps[0].1, json!({"dx": 1, "dy": 0}), "the original's steps are its own");
|
||||
}
|
||||
|
||||
/// The panel menu's Duplicate with a set selected copies the set and all its actions to right
|
||||
/// after it, with an id of its own, makes the copy current, and the copy is saved with the sets.
|
||||
#[test]
|
||||
fn the_panel_menus_duplicate_copies_the_current_set() {
|
||||
let mut app = app_with_sets();
|
||||
let ctx = egui::Context::default();
|
||||
click_set(&ctx, &mut app, "Mine", egui::Modifiers::NONE);
|
||||
menu_duplicate(&ctx, &mut app);
|
||||
assert_eq!(set_names(&app), ["Default Actions", "Mine", "Mine copy", "Other"]);
|
||||
assert_eq!(action_names(&app, 2), ["Nudge", "Nudge Again"], "every action is copied");
|
||||
assert_ne!(app.ui.action_sets[2].id, app.ui.action_sets[1].id, "the copy has an id of its own");
|
||||
assert_eq!((app.ui.action_set, app.ui.action_sets_selected.clone()), (Some(2), vec![2]), "the copy is current");
|
||||
app.ui.action_sets[2].actions[0].steps.clear();
|
||||
assert_eq!(app.ui.action_sets[1].actions[0].steps.len(), 1, "the original's steps are its own");
|
||||
let saved = serde_json::to_value(&app.ui).unwrap();
|
||||
let restored = serde_json::from_value::<crate::state::UiState>(saved).unwrap();
|
||||
assert_eq!(restored.action_sets.iter().map(|s| s.name.as_str()).collect::<Vec<_>>(), ["Default Actions", "Mine", "Mine copy", "Other"]);
|
||||
}
|
||||
|
||||
/// The panel menu's Duplicate does nothing while no action and no set is selected.
|
||||
#[test]
|
||||
fn the_panel_menus_duplicate_needs_a_selected_action_or_set() {
|
||||
let mut app = app_with_sets();
|
||||
let ctx = egui::Context::default();
|
||||
menu_duplicate(&ctx, &mut app);
|
||||
assert_eq!(set_names(&app), ["Default Actions", "Mine", "Other"]);
|
||||
assert_eq!(app.ui.action_sets.iter().map(|s| s.actions.len()).collect::<Vec<_>>(), [6, 2, 0]);
|
||||
assert_eq!(app.ui.action_set, None);
|
||||
}
|
||||
|
||||
/// `ui.actionSet.duplicate` copies an action or a set by index, the current set by default,
|
||||
/// refuses indexes past the last set or action, and keeps a recording and an open Batch dialog
|
||||
/// on their own set and action.
|
||||
#[test]
|
||||
fn the_duplicate_command_copies_by_index_and_keeps_recordings_and_dialogs_in_place() {
|
||||
let mut app = app_with_sets();
|
||||
assert_eq!(app.run(DUPLICATE, json!({})).unwrap_err(), "no action set is current");
|
||||
assert_eq!(app.run(DUPLICATE, json!({"set": 3})).unwrap_err(), "no such action set");
|
||||
assert_eq!(app.run(DUPLICATE, json!({"set": 1, "action": 2})).unwrap_err(), "no such action");
|
||||
assert_eq!(set_names(&app), ["Default Actions", "Mine", "Other"], "a refused index copies nothing");
|
||||
crate::dialogs::action_batch::open(&mut app, 1, 1).unwrap();
|
||||
assert_eq!(app.run(DUPLICATE, json!({"set": 1, "action": 0})).unwrap(), json!({"set": 1, "action": 1}));
|
||||
assert_eq!(action_names(&app, 1), ["Nudge", "Nudge copy", "Nudge Again"]);
|
||||
let d = app.ui.dialog.as_ref().expect("the Batch dialog stays open");
|
||||
assert_eq!((d.fields["set"].clone(), d.fields["action"].clone()), (json!(1), json!(2)), "it follows Nudge Again");
|
||||
app.ui.dialog = None;
|
||||
app.run("file.new", json!({"width": 200, "height": 100})).unwrap();
|
||||
let start = app.session.journal.len();
|
||||
app.session.journal.hold(Some(start));
|
||||
app.ui.recording = Some((2, "Action 1".into(), start));
|
||||
crate::dialogs::action_set_options::open(&mut app, 2);
|
||||
app.ui.action_set = Some(0);
|
||||
assert_eq!(app.run(DUPLICATE, json!({})).unwrap(), json!({"set": 1}), "the current set by default");
|
||||
assert_eq!(set_names(&app), ["Default Actions", "Default Actions copy", "Mine", "Other"]);
|
||||
assert_eq!(app.ui.recording.as_ref().map(|r| r.0), Some(3), "still recording into Other");
|
||||
assert_eq!(app.ui.dialog.as_ref().map(|d| d.fields["set"].clone()), Some(json!(3)), "Set Options still on Other");
|
||||
}
|
||||
|
||||
/// A recording keeps its steps when a canceled undo group drops journal entries made before the
|
||||
/// recording began.
|
||||
#[test]
|
||||
|
||||
@@ -1689,6 +1689,11 @@ already walks Image Trace. Short agent entry points:
|
||||
goes on in that set. The panel's Delete Selection (the trash button and the panel menu's Delete) asks before it runs
|
||||
this for the selected sets, and Shift-click on a set's name selects the sets from the current one to it. Undo does
|
||||
not restore a deleted set.
|
||||
`ui.actionSet.duplicate {set?: index, action?: index}` copies the action at `action` in set `set` to right after it
|
||||
in the same set, and returns `{set, action}`; without `action` it copies the set with all its actions to right after
|
||||
it, by default the current set, and returns `{set}`. The copy is named after the original with " copy" added, a
|
||||
copied set gets an id of its own, and the copy is selected. An index past the last set or action is an error. The
|
||||
panel menu's Duplicate runs this for the selected action, else the current set.
|
||||
- Image Trace: `imageTrace.presets`, `imageTrace.make {id?, preset?, params?, view?}` (or `imageTrace.makeAndExpand`),
|
||||
`imageTrace.setView`, `imageTrace.expand`, `imageTrace.release`. A key inside `params` that is not one of the trace
|
||||
settings, such as `colours`, is an error that names it and the nearest setting (`colors`), as for a command's own keys.
|
||||
|
||||
@@ -550,6 +550,7 @@ Moved from the ROADMAP's "Shipped so far" on 2026-10-10. Update it when a featur
|
||||
- Batch…: Override Save and Override Export name each file with the extension of the format the step writes, however the step spells the format (`.svg` and `SVG` give `.svg`, `png8` gives `.png`), in `action.batch`.
|
||||
- Actions panel (record/playback, persisted), generic parameter dialogs for every "…" command.
|
||||
- Actions panel: Delete Selection deletes the selected action set with its actions and keeps the other sets ([Actions panel overview](https://helpx.adobe.com/illustrator/desktop/automate-visualize-data/automate-actions/actions-panel-overview.html): "Removes the selected action, command, or action set from the panel"; `ui.actionSet.delete`). VectorCraft's own rules, which the overview does not cover: deleting a set asks first, Shift-click on a set's name selects a range of sets to delete together, the panel menu's Delete does the same, and Default Actions and the last set can be deleted. Undo does not bring a deleted set back.
|
||||
- Actions panel: the panel menu's Duplicate copies the selected action, else the current action set with all its actions ([Actions panel overview](https://helpx.adobe.com/illustrator/desktop/automate-visualize-data/automate-actions/actions-panel-overview.html): "Makes a copy of the selected action or set."; `ui.actionSet.duplicate`). VectorCraft's own rules, which the overview does not cover: the copy goes right after the original, is named after it with " copy" added and is selected.
|
||||
- Batch… over data sets names each file after the document and the data set (`action.batch`). It writes `/`, `\`, `:`, `<`, `>`, `"`, `|`, `?`, `*` and control characters in the data set's name as `-`, and adds `-2`, `-3`… to a name an earlier data set used.
|
||||
- Batch… offers File + Number, File + Data Set Name, and Data Set Name for a Data Sets source. The dialog defaults to File + Number; `action.batch` without `datasetFileNaming` keeps File + Data Set Name. An output already in a destination folder the batch may read and write gets the next free `-2`, `-3` suffix. [Batch options](https://helpx.adobe.com/illustrator/desktop/automate-visualize-data/automate-actions/batch-options.html).
|
||||
- Export for Screens: the dialog's Example line shows the path of the file the export writes first, sub-folder included, named as the export names it, for the first chosen artboard, asset, layer or object (`document.exportForScreens`).
|
||||
|
||||
@@ -299,6 +299,7 @@ next unit in the order a right-click on a ruler lists them, from Feet back to Po
|
||||
| Actions panel: a clicked action stays selected for Play Current Selection and Delete Selection | partial | #1853 (part of #1629); editing actions and action shortcuts remain |
|
||||
| Actions panel: Create New Set (bottom bar, ≡ › New Set…) names a new set and Set Options… renames the current one; a click on a set's name makes it current and a recording goes into the current set ([helpx: Automation with actions](https://helpx.adobe.com/illustrator/using/automation-actions.html)) | partial | #3712; the New Action dialog (name, set menu, shortcut, colour) and dragging actions between sets remain |
|
||||
| Actions panel: Delete Selection (bottom bar) deletes the selected set with its actions and keeps the other sets ([Actions panel overview](https://helpx.adobe.com/illustrator/desktop/automate-visualize-data/automate-actions/actions-panel-overview.html): "Removes the selected action, command, or action set from the panel") | partial | `ui.actionSet.delete`; `panels/actions.rs` tests. VectorCraft's own rules, which the overview does not cover: deleting a set asks first (a selected action is still deleted at once), Shift-click on a set's name selects a range of sets, ≡ › Delete does the same as the button, and Default Actions and the last set can be deleted. Undo does not restore a deleted set, and recorded commands cannot be selected or deleted |
|
||||
| Actions panel: ≡ › Duplicate copies the selected action or set ([Actions panel overview](https://helpx.adobe.com/illustrator/desktop/automate-visualize-data/automate-actions/actions-panel-overview.html): "Makes a copy of the selected action or set.") | partial | `ui.actionSet.duplicate`; `panels/actions.rs` tests. VectorCraft's own rules, which the overview does not cover: the copy goes right after the original, is named after it with " copy" added and is selected, and a copied set holds copies of all its actions. Undo does not remove the copy, and recorded commands cannot be duplicated |
|
||||
| Properties panel per context (every selection type's Quick Actions) | partial | one clip group: Edit Clipping Path and Edit Contents, at the top of the panel rather than in Quick Actions (G1); the overview's additional controls ([Properties panel overview](https://helpx.adobe.com/illustrator/desktop/get-started/learn-the-basics/properties-panel-overview.html)): Blend Options (one blend selected, with any tool, #4817) and Merge Live Paint (a Live Paint group with more) in Quick Actions, the Width Profile list (Width tool or a variable-width stroke) and an applied effect's Delete icon in Appearance, Corner and Corner Radius for corners selected with Direct Selection; Variable Font was already there |
|
||||
| Select › Start Global Edit / Stop Global Edit; Properties › Quick Actions with the Global Edit Options popover (Match: Appearance, Size; On Artboards: All Artboards or a range, Include Objects On Canvas; Result(s)); Escape stops it; the matched objects are highlighted in their layer colour while it runs | partial | #3521, `select.globalEdit` / `select.globalEditOptions`, `crates/engine/src/tests/globaledit.rs`; paths, compound paths, symbol instances and groups of them (similar groups, #4939: edits inside one group reach the same object in the others; [public source](https://helpx.adobe.com/illustrator/desktop/manage-objects/edit-objects/edit-groups-with-similar-objects.html)); the Control panel's copy of the options, Shift-click to leave a match out, rotated copies and highlighting matches before the start remain ([public source](https://helpx.adobe.com/illustrator/desktop/manage-objects/edit-objects/edit-similar-objects.html)) |
|
||||
| Contextual task bar | done | |
|
||||
|
||||
Reference in New Issue
Block a user