mirror of https://github.com/KLayout/klayout.git
Fixing issue #1864 (Copy & paste allows creating a recursive hierarchy)
This commit is contained in:
parent
ff708186ec
commit
5ece4d74ae
|
|
@ -156,6 +156,11 @@ ClipboardData::add (const db::Layout &layout, const db::Cell &cell, unsigned int
|
||||||
std::vector<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
|
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;
|
std::vector <unsigned int> new_layers;
|
||||||
PropertyMapper prop_id_map (&layout, &m_layout);
|
PropertyMapper prop_id_map (&layout, &m_layout);
|
||||||
|
|
||||||
|
|
@ -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) {
|
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::cell_index_type inst_cell = cell_map.find (inst->cell_index ())->second;
|
||||||
db::Instance new_inst = t.insert (*inst, im, prop_id_map);
|
if (callers.find (inst_cell) == callers.end ()) {
|
||||||
if (trans) {
|
|
||||||
new_inst = t.transform (new_inst, *trans);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (insert_receiver) {
|
tl::const_map<db::cell_index_type> im (inst_cell);
|
||||||
insert_receiver->instance_inserted (cp->second, new_inst);
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
} 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));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2667,8 +2667,22 @@ MainService::paste ()
|
||||||
{
|
{
|
||||||
if (view ()->is_editable ()) {
|
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 ();
|
int cv_index = view ()->active_cellview_index ();
|
||||||
|
|
||||||
const lay::CellView &cv = view ()->cellview (cv_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 ());
|
NewObjectsSelection insert_notification (cv_index, cv.cell_index (), view ());
|
||||||
|
|
||||||
|
|
@ -2678,14 +2692,8 @@ MainService::paste ()
|
||||||
for (db::Clipboard::iterator c = db::Clipboard::instance ().begin (); c != db::Clipboard::instance ().end (); ++c) {
|
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);
|
const db::ClipboardValue<edt::ClipboardData> *value = dynamic_cast<const db::ClipboardValue<edt::ClipboardData> *> (*c);
|
||||||
if (value) {
|
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);
|
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 ());
|
new_layers.insert (new_layers.end (), nl.begin (), nl.end ());
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue