Extract duplicate into core; support it in the script engine + wx GUI
A script using `duplicate` failed with "unsupported command 'duplicate'"
because the clone logic was still inline in the tui command. Extract it to
core/app/edit.hpp::duplicate_module(System*, src, dst) -> {ok, error, parts,
signals}: a deep clone of a module (parts, pins with spec + nc_origin, signals
with type overrides, pin→signal wiring; no connections), refusing on an unknown
source or an already-taken destination name.
- the tui `duplicate` command renders the result (output unchanged);
- the script engine dispatches `duplicate` to it — the failing script now runs;
- the wx GUI gains Edit ▸ Duplicate module… (PickModule + a name prompt).
tests/test_edit.cpp: deep clone wires to the clone's own signal (not the
source's) and preserves the type; unknown source / existing destination
refused. 412 core assertions green; tui + wx build clean.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -42,6 +42,7 @@ enum {
|
||||
ID_ATTACH_BSDL,
|
||||
ID_SET_SIGNAL_TYPE,
|
||||
ID_CONNECT,
|
||||
ID_DUPLICATE,
|
||||
ID_VERIFY,
|
||||
ID_QUIT,
|
||||
ID_ABOUT,
|
||||
@@ -132,6 +133,8 @@ EssimFrame::EssimFrame(WxFrontend &fe)
|
||||
edit->Append(ID_SET_SIGNAL_TYPE, "Set &signal type…\tCtrl-G");
|
||||
edit->AppendSeparator();
|
||||
edit->Append(ID_CONNECT, "C&onnect parts…\tCtrl-O");
|
||||
edit->AppendSeparator();
|
||||
edit->Append(ID_DUPLICATE, "&Duplicate module…\tCtrl-D");
|
||||
|
||||
auto *sysm = new wxMenu;
|
||||
sysm->Append(ID_VERIFY, "&Verify\tCtrl-K");
|
||||
@@ -195,6 +198,7 @@ EssimFrame::EssimFrame(WxFrontend &fe)
|
||||
Bind(wxEVT_MENU, &EssimFrame::OnAttachBsdl, this, ID_ATTACH_BSDL);
|
||||
Bind(wxEVT_MENU, &EssimFrame::OnSetSignalType, this, ID_SET_SIGNAL_TYPE);
|
||||
Bind(wxEVT_MENU, &EssimFrame::OnConnect, this, ID_CONNECT);
|
||||
Bind(wxEVT_MENU, &EssimFrame::OnDuplicateModule, this, ID_DUPLICATE);
|
||||
Bind(wxEVT_MENU, &EssimFrame::OnVerify, this, ID_VERIFY);
|
||||
Bind(wxEVT_MENU, &EssimFrame::OnQuit, this, ID_QUIT);
|
||||
Bind(wxEVT_MENU, &EssimFrame::OnAbout, this, ID_ABOUT);
|
||||
@@ -594,6 +598,29 @@ void EssimFrame::OnSetSignalType(wxCommandEvent &) {
|
||||
RebuildModelView();
|
||||
}
|
||||
|
||||
void EssimFrame::OnDuplicateModule(wxCommandEvent &) {
|
||||
Module *m = PickModule("Duplicate module");
|
||||
if (!m) return;
|
||||
const std::string src = m->name; // m may move in the table after the add
|
||||
|
||||
wxTextEntryDialog dlg(this, "New module name:", "Duplicate module",
|
||||
wx(src) + "_copy");
|
||||
if (dlg.ShowModal() != wxID_OK) return;
|
||||
const std::string dst = dlg.GetValue().utf8_string();
|
||||
if (dst.empty()) return;
|
||||
|
||||
app::DuplicateResult r = app::duplicate_module(fe_.system(), src, dst);
|
||||
if (!r.ok) {
|
||||
Log(wx(r.error));
|
||||
wxMessageBox(wx(r.error), "Duplicate module", wxOK | wxICON_ERROR, this);
|
||||
return;
|
||||
}
|
||||
Log(wx("duplicate: '" + src + "' → '" + dst + "' ("
|
||||
+ std::to_string(r.parts) + " part(s), "
|
||||
+ std::to_string(r.signals) + " signal(s))"));
|
||||
RebuildModelView();
|
||||
}
|
||||
|
||||
void EssimFrame::OnVerify(wxCommandEvent &) {
|
||||
app::VerifyReport r = app::verify(fe_.system());
|
||||
|
||||
|
||||
Reference in New Issue
Block a user