forked from 1b-agent/opencadstudio-upstream
Selection: count duplicates and removals from the step's own picks
The count line now uses the objects the selection step itself picked (a click, a window or crossing, a lasso, a fence, Last / Previous / All): "N found (D duplicate), M total" when some were chosen already, "N found, R removed, M total" in remove mode, "N found, M total" when a removal picks objects that were not chosen. Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
1e93b16911
commit
b9fd0a066c
27 files changed
+71
-12
No files matched your search
@@ -6555,4 +6555,5 @@ keytips =
|
||||
.hint-items = اكتب حرف العنصر · Esc للرجوع مستوى واحدًا
|
||||
|
||||
selection-report =
|
||||
.found-duplicate-total = __ocs_fmt_0__ found (__ocs_fmt_1__ duplicate), __ocs_fmt_2__ total
|
||||
.found-removed-total = __ocs_fmt_0__ found, __ocs_fmt_1__ removed, __ocs_fmt_2__ total
|
||||
@@ -6543,4 +6543,5 @@ keytips =
|
||||
.hint-items = Въведете буква на елемент · Esc връща едно ниво назад
|
||||
|
||||
selection-report =
|
||||
.found-duplicate-total = __ocs_fmt_0__ found (__ocs_fmt_1__ duplicate), __ocs_fmt_2__ total
|
||||
.found-removed-total = __ocs_fmt_0__ found, __ocs_fmt_1__ removed, __ocs_fmt_2__ total
|
||||
@@ -6540,4 +6540,5 @@ keytips =
|
||||
.hint-items = Zadejte písmeno položky · Esc o úroveň zpět
|
||||
|
||||
selection-report =
|
||||
.found-duplicate-total = __ocs_fmt_0__ found (__ocs_fmt_1__ duplicate), __ocs_fmt_2__ total
|
||||
.found-removed-total = __ocs_fmt_0__ found, __ocs_fmt_1__ removed, __ocs_fmt_2__ total
|
||||
@@ -6541,4 +6541,5 @@ keytips =
|
||||
.hint-items = Buchstaben eines Elements eingeben · Esc geht eine Ebene zurück
|
||||
|
||||
selection-report =
|
||||
.found-duplicate-total = __ocs_fmt_0__ found (__ocs_fmt_1__ duplicate), __ocs_fmt_2__ total
|
||||
.found-removed-total = __ocs_fmt_0__ found, __ocs_fmt_1__ removed, __ocs_fmt_2__ total
|
||||
@@ -6543,4 +6543,5 @@ keytips =
|
||||
.hint-items = Πληκτρολογήστε γράμμα στοιχείου · Το Esc επιστρέφει ένα επίπεδο
|
||||
|
||||
selection-report =
|
||||
.found-duplicate-total = __ocs_fmt_0__ found (__ocs_fmt_1__ duplicate), __ocs_fmt_2__ total
|
||||
.found-removed-total = __ocs_fmt_0__ found, __ocs_fmt_1__ removed, __ocs_fmt_2__ total
|
||||
@@ -6542,4 +6542,5 @@ keytips =
|
||||
.hint-items = Type an item letter · Esc goes back one level
|
||||
|
||||
selection-report =
|
||||
.found-duplicate-total = __ocs_fmt_0__ found (__ocs_fmt_1__ duplicate), __ocs_fmt_2__ total
|
||||
.found-removed-total = __ocs_fmt_0__ found, __ocs_fmt_1__ removed, __ocs_fmt_2__ total
|
||||
@@ -6543,4 +6543,5 @@ keytips =
|
||||
.hint-items = Escriba la letra de un elemento · Esc retrocede un nivel
|
||||
|
||||
selection-report =
|
||||
.found-duplicate-total = __ocs_fmt_0__ found (__ocs_fmt_1__ duplicate), __ocs_fmt_2__ total
|
||||
.found-removed-total = __ocs_fmt_0__ found, __ocs_fmt_1__ removed, __ocs_fmt_2__ total
|
||||
@@ -6540,4 +6540,5 @@ keytips =
|
||||
.hint-items = Kirjoita kohteen kirjain · Esc palaa tason taaksepäin
|
||||
|
||||
selection-report =
|
||||
.found-duplicate-total = __ocs_fmt_0__ found (__ocs_fmt_1__ duplicate), __ocs_fmt_2__ total
|
||||
.found-removed-total = __ocs_fmt_0__ found, __ocs_fmt_1__ removed, __ocs_fmt_2__ total
|
||||
@@ -6543,4 +6543,5 @@ keytips =
|
||||
.hint-items = Tapez la lettre d'un élément · Échap remonte d'un niveau
|
||||
|
||||
selection-report =
|
||||
.found-duplicate-total = __ocs_fmt_0__ found (__ocs_fmt_1__ duplicate), __ocs_fmt_2__ total
|
||||
.found-removed-total = __ocs_fmt_0__ found, __ocs_fmt_1__ removed, __ocs_fmt_2__ total
|
||||
@@ -6531,4 +6531,5 @@ keytips =
|
||||
.hint-items = आइटम का अक्षर टाइप करें · Esc एक स्तर पीछे जाता है
|
||||
|
||||
selection-report =
|
||||
.found-duplicate-total = __ocs_fmt_0__ found (__ocs_fmt_1__ duplicate), __ocs_fmt_2__ total
|
||||
.found-removed-total = __ocs_fmt_0__ found, __ocs_fmt_1__ removed, __ocs_fmt_2__ total
|
||||
@@ -6527,4 +6527,5 @@ keytips =
|
||||
.hint-items = Írja be az elem betűjét · Az Esc egy szinttel visszalép
|
||||
|
||||
selection-report =
|
||||
.found-duplicate-total = __ocs_fmt_0__ found (__ocs_fmt_1__ duplicate), __ocs_fmt_2__ total
|
||||
.found-removed-total = __ocs_fmt_0__ found, __ocs_fmt_1__ removed, __ocs_fmt_2__ total
|
||||
@@ -6542,4 +6542,5 @@ keytips =
|
||||
.hint-items = Digitare la lettera di un elemento · Esc torna indietro di un livello
|
||||
|
||||
selection-report =
|
||||
.found-duplicate-total = __ocs_fmt_0__ found (__ocs_fmt_1__ duplicate), __ocs_fmt_2__ total
|
||||
.found-removed-total = __ocs_fmt_0__ found, __ocs_fmt_1__ removed, __ocs_fmt_2__ total
|
||||
@@ -6531,4 +6531,5 @@ keytips =
|
||||
.hint-items = 項目の文字を入力 · Esc で 1 つ上に戻る
|
||||
|
||||
selection-report =
|
||||
.found-duplicate-total = __ocs_fmt_0__ found (__ocs_fmt_1__ duplicate), __ocs_fmt_2__ total
|
||||
.found-removed-total = __ocs_fmt_0__ found, __ocs_fmt_1__ removed, __ocs_fmt_2__ total
|
||||
@@ -6542,4 +6542,5 @@ keytips =
|
||||
.hint-items = 항목 문자를 입력하십시오 · Esc로 한 단계 뒤로
|
||||
|
||||
selection-report =
|
||||
.found-duplicate-total = __ocs_fmt_0__ found (__ocs_fmt_1__ duplicate), __ocs_fmt_2__ total
|
||||
.found-removed-total = __ocs_fmt_0__ found, __ocs_fmt_1__ removed, __ocs_fmt_2__ total
|
||||
@@ -6543,4 +6543,5 @@ keytips =
|
||||
.hint-items = ພິມຕົວອັກສອນລາຍການ · Esc ກັບຄືນໜຶ່ງລະດັບ
|
||||
|
||||
selection-report =
|
||||
.found-duplicate-total = __ocs_fmt_0__ found (__ocs_fmt_1__ duplicate), __ocs_fmt_2__ total
|
||||
.found-removed-total = __ocs_fmt_0__ found, __ocs_fmt_1__ removed, __ocs_fmt_2__ total
|
||||
@@ -6541,4 +6541,5 @@ keytips =
|
||||
.hint-items = Typ de letter van een item · Esc gaat één niveau terug
|
||||
|
||||
selection-report =
|
||||
.found-duplicate-total = __ocs_fmt_0__ found (__ocs_fmt_1__ duplicate), __ocs_fmt_2__ total
|
||||
.found-removed-total = __ocs_fmt_0__ found, __ocs_fmt_1__ removed, __ocs_fmt_2__ total
|
||||
@@ -6542,4 +6542,5 @@ keytips =
|
||||
.hint-items = Wpisz literę elementu · Esc cofa o jeden poziom
|
||||
|
||||
selection-report =
|
||||
.found-duplicate-total = __ocs_fmt_0__ found (__ocs_fmt_1__ duplicate), __ocs_fmt_2__ total
|
||||
.found-removed-total = __ocs_fmt_0__ found, __ocs_fmt_1__ removed, __ocs_fmt_2__ total
|
||||
@@ -6543,4 +6543,5 @@ keytips =
|
||||
.hint-items = Digite a letra de um item · Esc volta um nível
|
||||
|
||||
selection-report =
|
||||
.found-duplicate-total = __ocs_fmt_0__ found (__ocs_fmt_1__ duplicate), __ocs_fmt_2__ total
|
||||
.found-removed-total = __ocs_fmt_0__ found, __ocs_fmt_1__ removed, __ocs_fmt_2__ total
|
||||
@@ -6544,4 +6544,5 @@ keytips =
|
||||
.hint-items = Введите букву элемента · Esc — на уровень назад
|
||||
|
||||
selection-report =
|
||||
.found-duplicate-total = __ocs_fmt_0__ found (__ocs_fmt_1__ duplicate), __ocs_fmt_2__ total
|
||||
.found-removed-total = __ocs_fmt_0__ found, __ocs_fmt_1__ removed, __ocs_fmt_2__ total
|
||||
@@ -6464,4 +6464,5 @@ keytips =
|
||||
.hint-items = Öğe harfini yazın · Esc bir düzey geri
|
||||
|
||||
selection-report =
|
||||
.found-duplicate-total = __ocs_fmt_0__ bulundu (__ocs_fmt_1__ yinelenen), toplam __ocs_fmt_2__
|
||||
.found-removed-total = __ocs_fmt_0__ bulundu, __ocs_fmt_1__ çıkarıldı, toplam __ocs_fmt_2__
|
||||
@@ -6526,4 +6526,5 @@ keytips =
|
||||
.hint-items = 键入项目字母 · Esc 返回上一级
|
||||
|
||||
selection-report =
|
||||
.found-duplicate-total = __ocs_fmt_0__ found (__ocs_fmt_1__ duplicate), __ocs_fmt_2__ total
|
||||
.found-removed-total = __ocs_fmt_0__ found, __ocs_fmt_1__ removed, __ocs_fmt_2__ total
|
||||
@@ -6538,4 +6538,5 @@ keytips =
|
||||
.hint-items = 輸入項目字母 · Esc 返回上一層
|
||||
|
||||
selection-report =
|
||||
.found-duplicate-total = __ocs_fmt_0__ found (__ocs_fmt_1__ duplicate), __ocs_fmt_2__ total
|
||||
.found-removed-total = __ocs_fmt_0__ found, __ocs_fmt_1__ removed, __ocs_fmt_2__ total
|
||||
@@ -1244,6 +1244,7 @@ impl OpenCADStudio {
|
||||
bounds,
|
||||
|point| self.cursor_model_point(i, &edit_cam, point, bounds),
|
||||
);
|
||||
self.last_pick = Some((handles.clone(), self.select_remove_mode));
|
||||
if self.select_remove_mode {
|
||||
for h in &handles {
|
||||
self.tabs[i].scene.deselect_entity(*h);
|
||||
|
||||
@@ -574,16 +574,16 @@ impl OpenCADStudio {
|
||||
StepInput::SelectionComplete(kept)
|
||||
}
|
||||
|
||||
/// What one pick added to (or removed from) a gathering selection, as the
|
||||
/// reference words it: `N found`, `N found, M total`, `N found, N removed,
|
||||
/// M total`. Returns the command's key while it gathers.
|
||||
// ponytail: compares the whole selection before and after, so a pick of an
|
||||
// already chosen object reads `0 found` (the reference says `1 found (1
|
||||
// duplicate)`); pass the pick's own objects through StepInput if needed.
|
||||
/// What one selection step picked, as the reference words it: `N found`
|
||||
/// for the first step, `N found, M total`, `N found (D duplicate), M
|
||||
/// total` when some were chosen already, `N found, R removed, M total` in
|
||||
/// remove mode. Returns the command's key while it gathers.
|
||||
fn report_selection_found(&mut self, input: &StepInput) -> Option<usize> {
|
||||
let StepInput::SelectionComplete(handles) = input else {
|
||||
return None;
|
||||
};
|
||||
// A pick belongs to this step only; never to a later one.
|
||||
let last_pick = self.last_pick.take();
|
||||
let command = self.tabs[self.active_tab].active_cmd.as_ref()?;
|
||||
if !command.is_selection_gathering() {
|
||||
return None;
|
||||
@@ -594,13 +594,29 @@ impl OpenCADStudio {
|
||||
_ => Default::default(),
|
||||
};
|
||||
let now: rustc_hash::FxHashSet<Handle> = handles.iter().copied().collect();
|
||||
let found = now.difference(&previous).count();
|
||||
let removed = previous.difference(&now).count();
|
||||
let total = now.len();
|
||||
let line = if removed > 0 {
|
||||
crate::tf!("{removed} found, {removed} removed, {total} total")
|
||||
} else if found == 0 || previous.is_empty() {
|
||||
// What the step picked: its own objects when the pick says so, else
|
||||
// what the selection gained or lost.
|
||||
let (picked, remove) = match last_pick {
|
||||
Some((picked, remove)) => (picked.into_iter().collect(), remove),
|
||||
None => {
|
||||
let lost: rustc_hash::FxHashSet<Handle> =
|
||||
previous.difference(&now).copied().collect();
|
||||
if lost.is_empty() {
|
||||
(now.difference(&previous).copied().collect(), false)
|
||||
} else {
|
||||
(lost, true)
|
||||
}
|
||||
}
|
||||
};
|
||||
let found = picked.len();
|
||||
let known = picked.intersection(&previous).count();
|
||||
let line = if found == 0 || previous.is_empty() && !remove {
|
||||
crate::tf!("{found} found")
|
||||
} else if remove && known > 0 {
|
||||
crate::tf!("{found} found, {known} removed, {total} total")
|
||||
} else if !remove && known > 0 {
|
||||
crate::tf!("{found} found ({known} duplicate), {total} total")
|
||||
} else {
|
||||
crate::tf!("{found} found, {total} total")
|
||||
};
|
||||
@@ -1083,6 +1099,7 @@ impl OpenCADStudio {
|
||||
);
|
||||
return Some(Task::none());
|
||||
}
|
||||
self.last_pick = Some((add.clone(), false));
|
||||
for h in add {
|
||||
self.tabs[i].scene.select_entity(h, false);
|
||||
}
|
||||
|
||||
@@ -799,6 +799,9 @@ pub(super) struct OpenCADStudio {
|
||||
/// The selection the gathering command had after the last pick (keyed by
|
||||
/// the command), for the `N found, M total` line.
|
||||
pub(crate) selection_report: Option<(usize, Vec<codec::Handle>)>,
|
||||
/// The objects the last selection step picked (a click, a window, a
|
||||
/// fence, Last / Previous / All) and whether it removed them.
|
||||
pub(crate) last_pick: Option<(Vec<codec::Handle>, bool)>,
|
||||
/// The Edit Reference dialog's remembered settings.
|
||||
pub(crate) refedit_options: crate::app::settings::RefEditOptions,
|
||||
/// BLOCKREDEFINEMODE (0–2).
|
||||
@@ -4686,6 +4689,7 @@ impl OpenCADStudio {
|
||||
block_freq: std::collections::HashMap::new(),
|
||||
block_mru_list: 50,
|
||||
selection_report: None,
|
||||
last_pick: None,
|
||||
refedit_options: Default::default(),
|
||||
block_redefine_mode: 1,
|
||||
block_navigate: ".".to_string(),
|
||||
|
||||
@@ -5215,6 +5215,10 @@ properties={:.1}ms picked={}",
|
||||
// lasso adds, Shift+lasso removes. An empty lasso
|
||||
// leaves the current selection untouched so a stray
|
||||
// drag never discards hard-won picks.
|
||||
if is_gathering {
|
||||
self.last_pick =
|
||||
Some((handles.clone(), self.shift_down || self.select_remove_mode));
|
||||
}
|
||||
if self.shift_down || self.select_remove_mode {
|
||||
self.tabs[i].scene.deselect_entities(&handles);
|
||||
} else {
|
||||
@@ -5356,6 +5360,12 @@ properties={:.1}ms picked={}",
|
||||
let hit =
|
||||
hit.filter(|&h| self.tabs[i].scene.passes_selection_filter(h));
|
||||
if let Some(handle) = hit {
|
||||
if is_gathering {
|
||||
self.last_pick = Some((
|
||||
vec![handle],
|
||||
self.shift_down || self.select_remove_mode,
|
||||
));
|
||||
}
|
||||
// Individual picks accumulate (issue #47):
|
||||
// each plain click adds to the selection,
|
||||
// Shift+click removes the picked entity.
|
||||
@@ -5488,6 +5498,10 @@ was_selected={}",
|
||||
// entities. An empty box leaves the selection alone
|
||||
// so an accidental empty drag never discards it.
|
||||
// PICKADD 0 (#226): a plain box REPLACES instead.
|
||||
if is_gathering {
|
||||
self.last_pick =
|
||||
Some((handles.clone(), self.shift_down || self.select_remove_mode));
|
||||
}
|
||||
if self.shift_down || self.select_remove_mode {
|
||||
self.tabs[i].scene.deselect_entities(&handles);
|
||||
} else {
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
|
||||
pub(super) fn message_attribute(source: &str) -> Option<(&'static str, &'static str)> {
|
||||
match source {
|
||||
"{removed} found, {removed} removed, {total} total" => Some(("selection-report", "found-removed-total")),
|
||||
"{found} found, {known} removed, {total} total" => Some(("selection-report", "found-removed-total")),
|
||||
"{found} found ({known} duplicate), {total} total" => Some(("selection-report", "found-duplicate-total")),
|
||||
"Add to Working Set" => Some(("ref-edit", "add-to-working-set")),
|
||||
"Remove from Working Set" => Some(("ref-edit", "remove-from-working-set")),
|
||||
"Select reference:" => Some(("ref-edit", "select-reference")),
|
||||
|
||||
Reference in new issue
Block a user