Skip to content

Commit

Permalink
Fixing issue #1864 (Copy & paste allows creating a recursive hierarchy)
Browse files Browse the repository at this point in the history
  • Loading branch information
Matthias Koefferlein committed Sep 20, 2024
1 parent ff70818 commit 5ece4d7
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 13 deletions.
26 changes: 19 additions & 7 deletions src/db/db/dbClipboardData.cc
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,11 @@ ClipboardData::add (const db::Layout &layout, const db::Cell &cell, unsigned int
std::vector<unsigned int>
ClipboardData::do_insert (db::Layout &layout, const db::ICplxTrans *trans, db::Cell *cell, std::vector<db::cell_index_type> *new_tops, ClipboardDataInsertReceiver *insert_receiver) const
{
// identify the cells our target is eventually called from, including itself
std::set<db::cell_index_type> callers;
cell->collect_caller_cells (callers);
callers.insert (cell->cell_index ());

std::vector <unsigned int> new_layers;
PropertyMapper prop_id_map (&layout, &m_layout);

Expand Down Expand Up @@ -279,14 +284,21 @@ ClipboardData::do_insert (db::Layout &layout, const db::ICplxTrans *trans, db::C

for (db::Cell::const_iterator inst = c->begin (); ! inst.at_end (); ++inst) {

tl::const_map<db::cell_index_type> im (cell_map.find (inst->cell_index ())->second);
db::Instance new_inst = t.insert (*inst, im, prop_id_map);
if (trans) {
new_inst = t.transform (new_inst, *trans);
}
db::cell_index_type inst_cell = cell_map.find (inst->cell_index ())->second;
if (callers.find (inst_cell) == callers.end ()) {

tl::const_map<db::cell_index_type> im (inst_cell);
db::Instance new_inst = t.insert (*inst, im, prop_id_map);
if (trans) {
new_inst = t.transform (new_inst, *trans);
}

if (insert_receiver) {
insert_receiver->instance_inserted (cp->second, new_inst);
if (insert_receiver) {
insert_receiver->instance_inserted (cp->second, new_inst);
}

} else {
tl::warn << tl::sprintf (tl::to_string (tr ("Refusing to paste an instance for cell %s, as this would create a recursive hierarchy")), layout.cell_name (inst_cell));
}

}
Expand Down
20 changes: 14 additions & 6 deletions src/edt/edt/edtMainService.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2667,8 +2667,22 @@ MainService::paste ()
{
if (view ()->is_editable ()) {

// skip, if there is nothing to insert
bool any = false;
for (db::Clipboard::iterator c = db::Clipboard::instance ().begin (); c != db::Clipboard::instance ().end () && ! any; ++c) {
const db::ClipboardValue<edt::ClipboardData> *value = dynamic_cast<const db::ClipboardValue<edt::ClipboardData> *> (*c);
any = (value != 0);
}
if (! any) {
return;
}

int cv_index = view ()->active_cellview_index ();

const lay::CellView &cv = view ()->cellview (cv_index);
if (! cv.is_valid ()) {
throw tl::Exception (tl::to_string (tr ("No cell selected to paste something into")));
}

NewObjectsSelection insert_notification (cv_index, cv.cell_index (), view ());

Expand All @@ -2678,14 +2692,8 @@ MainService::paste ()
for (db::Clipboard::iterator c = db::Clipboard::instance ().begin (); c != db::Clipboard::instance ().end (); ++c) {
const db::ClipboardValue<edt::ClipboardData> *value = dynamic_cast<const db::ClipboardValue<edt::ClipboardData> *> (*c);
if (value) {

if (! cv.is_valid ()) {
throw tl::Exception (tl::to_string (tr ("No cell selected to paste something into")));
}

std::vector<unsigned int> nl = value->get ().insert (cv->layout (), cv.context_trans ().inverted (), &cv->layout ().cell (cv.cell_index ()), 0 /*new_tops*/, &insert_notification);
new_layers.insert (new_layers.end (), nl.begin (), nl.end ());

}
}

Expand Down

0 comments on commit 5ece4d7

Please sign in to comment.