forked from 1b-agent/opencadstudio-upstream
Merge main into Pallet-placement
Resolved conflicts: - app/update/mod.rs: keep the dock's dock_open_at_default for the XREF manager; take main's stable xref row identity (row_index(&id)). - app/view/mod.rs: keep the edge layout from app::dock; drop main's copy of the old edge-stack code (main only reformatted it there). - ui/window/layers.rs: keep main's new visible_indices next to the branch's view_panel. Files the branch only reformatted take main's version. Adds the Lao (lo-LA) translations for the new dock texts. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_013RyGiMXcsf9HTKfqDxaQGt
This commit is contained in:
136 files changed
+12408
-949
No files matched your search
+56
-20
@@ -1514,13 +1514,42 @@ mod tests {
|
||||
.join("\n")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn xref_rowop_unknown_id_is_noop() {
|
||||
// #49 RED: row messages carry (key, saved_path) identity and resolve
|
||||
// at dispatch; a deleted row's id must no-op instead of hitting whatever
|
||||
// row now sits at the old index. Fails to compile until the payload
|
||||
// carries XrefRowId instead of usize.
|
||||
use crate::app::Message;
|
||||
use crate::ui::window::xref_manager::{XrefPaletteOp, XrefRowId};
|
||||
let mut app = fresh();
|
||||
let i = app.active_tab;
|
||||
let start = app.command_line.history.len();
|
||||
let ghost = XrefRowId {
|
||||
key: u64::MAX,
|
||||
saved_path: "gone.dwg".to_string(),
|
||||
};
|
||||
let records_before = app.tabs[i].scene.document.block_records.iter().count();
|
||||
let _ = app.update(Message::XrefRowOp(ghost, XrefPaletteOp::Detach));
|
||||
assert_eq!(
|
||||
app.tabs[i].scene.document.block_records.iter().count(),
|
||||
records_before,
|
||||
"no-op must not disturb the document"
|
||||
);
|
||||
let out = palette_output(&app, start);
|
||||
assert!(
|
||||
!out.contains("detached"),
|
||||
"unknown id must not detach anything, got: {out:?}"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn palette_rowop_nested_reports_per_entry() {
|
||||
// Behavioral matrix: every row op on a NESTED row via the GUI
|
||||
// message path. Nested rows must report per-entry errors (CLI
|
||||
// wording), never silently skip.
|
||||
use crate::app::Message;
|
||||
use crate::ui::window::xref_manager::XrefPaletteOp;
|
||||
use crate::ui::window::xref_manager::{XrefPaletteOp, XrefRowId};
|
||||
use codec::tables::BlockRecord;
|
||||
let dir = palette_tmpdir("nestedmatrix");
|
||||
let mut host_doc = codec::CadDocument::new();
|
||||
@@ -1539,13 +1568,14 @@ mod tests {
|
||||
app.tabs[i].scene.document.block_records.add(br).unwrap();
|
||||
app.tabs[i].current_path = Some(dir.join("app.dwg"));
|
||||
app.refresh_xref_manager();
|
||||
let idx = app
|
||||
let row = app
|
||||
.xref_manager
|
||||
.entries
|
||||
.iter()
|
||||
.position(|e| e.name == "INNER")
|
||||
.find(|e| e.name == "INNER")
|
||||
.expect("nested INNER listed");
|
||||
assert!(app.xref_manager.entries[idx].parent_key.is_some());
|
||||
assert!(row.parent_key.is_some());
|
||||
let row_id = XrefRowId::of(row.key, &row.saved_path);
|
||||
for op in [
|
||||
XrefPaletteOp::Detach,
|
||||
XrefPaletteOp::Unload,
|
||||
@@ -1554,7 +1584,7 @@ mod tests {
|
||||
XrefPaletteOp::Overlay,
|
||||
] {
|
||||
let start = app.command_line.history.len();
|
||||
let _ = app.update(Message::XrefRowOp(idx, op));
|
||||
let _ = app.update(Message::XrefRowOp(row_id.clone(), op));
|
||||
let out = palette_output(&app, start);
|
||||
assert!(
|
||||
out.contains("INNER"),
|
||||
@@ -1578,7 +1608,7 @@ mod tests {
|
||||
// Reproduction for "Detach/Unload from the palette do nothing":
|
||||
// drive the exact GUI message path (row right-click menu item).
|
||||
use crate::app::Message;
|
||||
use crate::ui::window::xref_manager::XrefPaletteOp;
|
||||
use crate::ui::window::xref_manager::{XrefPaletteOp, XrefRowId};
|
||||
use codec::tables::BlockRecord;
|
||||
let mut app = fresh();
|
||||
let i = app.active_tab;
|
||||
@@ -1591,14 +1621,16 @@ mod tests {
|
||||
}
|
||||
app.tabs[i].current_path = Some(std::env::temp_dir().join("ocs_repro_host.dwg"));
|
||||
app.refresh_xref_manager();
|
||||
let idx = app
|
||||
let plan = app
|
||||
.xref_manager
|
||||
.entries
|
||||
.iter()
|
||||
.position(|e| e.name == "PLAN")
|
||||
.expect("PLAN listed");
|
||||
.find(|e| e.name == "PLAN")
|
||||
.expect("PLAN listed")
|
||||
.clone();
|
||||
let plan_id = XrefRowId::of(plan.key, &plan.saved_path);
|
||||
let start = app.command_line.history.len();
|
||||
let _ = app.update(Message::XrefRowOp(idx, XrefPaletteOp::Detach));
|
||||
let _ = app.update(Message::XrefRowOp(plan_id, XrefPaletteOp::Detach));
|
||||
let out = palette_output(&app, start);
|
||||
assert!(out.contains("PLAN"), "detach output missing, got: {out:?}");
|
||||
assert!(
|
||||
@@ -1610,14 +1642,16 @@ mod tests {
|
||||
.is_none(),
|
||||
"PLAN definition must be gone"
|
||||
);
|
||||
let idx = app
|
||||
let site = app
|
||||
.xref_manager
|
||||
.entries
|
||||
.iter()
|
||||
.position(|e| e.name == "SITE")
|
||||
.expect("SITE listed");
|
||||
.find(|e| e.name == "SITE")
|
||||
.expect("SITE listed")
|
||||
.clone();
|
||||
let site_id = XrefRowId::of(site.key, &site.saved_path);
|
||||
let start = app.command_line.history.len();
|
||||
let _ = app.update(Message::XrefRowOp(idx, XrefPaletteOp::Unload));
|
||||
let _ = app.update(Message::XrefRowOp(site_id, XrefPaletteOp::Unload));
|
||||
let out = palette_output(&app, start);
|
||||
assert!(out.contains("SITE"), "unload output missing, got: {out:?}");
|
||||
assert_eq!(
|
||||
@@ -1637,7 +1671,7 @@ mod tests {
|
||||
// GUI message path: type flag flips, saved path clears.
|
||||
use crate::app::Message;
|
||||
use crate::io::xref_model::{Pathtype, RefType};
|
||||
use crate::ui::window::xref_manager::XrefPaletteOp;
|
||||
use crate::ui::window::xref_manager::{XrefPaletteOp, XrefRowId};
|
||||
use codec::tables::BlockRecord;
|
||||
let mut app = fresh();
|
||||
let i = app.active_tab;
|
||||
@@ -1648,14 +1682,16 @@ mod tests {
|
||||
app.tabs[i].scene.document.block_records.add(br).unwrap();
|
||||
app.tabs[i].current_path = Some(std::env::temp_dir().join("ocs_rowop_host.dwg"));
|
||||
app.refresh_xref_manager();
|
||||
let idx = app
|
||||
let plan = app
|
||||
.xref_manager
|
||||
.entries
|
||||
.iter()
|
||||
.position(|e| e.name == "PLAN")
|
||||
.expect("PLAN listed");
|
||||
.find(|e| e.name == "PLAN")
|
||||
.expect("PLAN listed")
|
||||
.clone();
|
||||
let plan_id = XrefRowId::of(plan.key, &plan.saved_path);
|
||||
let start = app.command_line.history.len();
|
||||
let _ = app.update(Message::XrefRowOp(idx, XrefPaletteOp::Overlay));
|
||||
let _ = app.update(Message::XrefRowOp(plan_id.clone(), XrefPaletteOp::Overlay));
|
||||
let out = palette_output(&app, start);
|
||||
assert!(out.contains("PLAN"), "got: {out:?}");
|
||||
let br = app.tabs[i]
|
||||
@@ -1676,7 +1712,7 @@ mod tests {
|
||||
);
|
||||
let start = app.command_line.history.len();
|
||||
let _ = app.update(Message::XrefRowOp(
|
||||
idx,
|
||||
plan_id,
|
||||
XrefPaletteOp::Pathtype(Pathtype::None),
|
||||
));
|
||||
let out = palette_output(&app, start);
|
||||
|
||||
Reference in new issue
Block a user