mirror of
https://github.com/KLayout/klayout.git
synced 2026-09-03 07:03:05 +02:00
Fixed #951
The problem was essentially the "specific path" which got invalid. The solution is to establish a better criterion for "path validity" and use for failsafes against invalid paths. In addition, the path validation has been modified such that a better choice is made about the remaining path after a cell gets deleted.
This commit is contained in:
@@ -501,13 +501,13 @@ CellView::is_valid () const
|
||||
}
|
||||
|
||||
// check, if the path references valid cell indices.
|
||||
for (specific_cell_path_type::const_iterator pp = m_specific_path.begin (); pp != m_specific_path.end (); ++pp) {
|
||||
if (! m_layout_href.get ()->layout ().is_valid_cell_index (pp->inst_ptr.cell_index ())) {
|
||||
for (unspecific_cell_path_type::const_iterator pp = m_unspecific_path.begin (); pp != m_unspecific_path.end (); ++pp) {
|
||||
if (! m_layout_href.get ()->layout ().is_valid_cell_index (*pp)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
for (unspecific_cell_path_type::const_iterator pp = m_unspecific_path.begin (); pp != m_unspecific_path.end (); ++pp) {
|
||||
if (! m_layout_href.get ()->layout ().is_valid_cell_index (*pp)) {
|
||||
for (specific_cell_path_type::const_iterator pp = m_specific_path.begin (); pp != m_specific_path.end (); ++pp) {
|
||||
if (! pp->inst_ptr.instances () || ! pp->inst_ptr.instances ()->is_valid (pp->inst_ptr) || ! m_layout_href.get ()->layout ().is_valid_cell_index (pp->inst_ptr.cell_index ())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -836,6 +836,8 @@ HierarchyControlPanel::do_update_content (int cv_index)
|
||||
if (&m_cellviews [i]->layout () != &mp_view->cellview (i)->layout ()) {
|
||||
m_needs_update [i] = true;
|
||||
m_force_close [i] = true;
|
||||
} else if (! m_cellviews [i].is_valid ()) {
|
||||
m_needs_update [i] = true;
|
||||
} else if (m_cellviews [i].combined_unspecific_path () != mp_view->cellview (i).combined_unspecific_path ()) {
|
||||
m_needs_update [i] = true;
|
||||
}
|
||||
|
||||
@@ -4896,6 +4896,7 @@ LayoutView::select_cell_fit (const cell_path_type &path, int index)
|
||||
|
||||
set_min_hier_levels (0);
|
||||
cancel ();
|
||||
cellview_iter (index)->set_specific_path (lay::CellView::specific_cell_path_type ());
|
||||
cellview_iter (index)->set_unspecific_path (path);
|
||||
set_active_cellview_index (index);
|
||||
redraw ();
|
||||
@@ -4985,6 +4986,7 @@ LayoutView::select_cell (const cell_path_type &path, int index)
|
||||
|
||||
set_min_hier_levels (0);
|
||||
cancel ();
|
||||
cellview_iter (index)->set_specific_path (lay::CellView::specific_cell_path_type ());
|
||||
cellview_iter (index)->set_unspecific_path (path);
|
||||
set_active_cellview_index (index);
|
||||
redraw ();
|
||||
|
||||
@@ -42,6 +42,41 @@
|
||||
namespace lay
|
||||
{
|
||||
|
||||
static void
|
||||
collect_cells_to_delete (const db::Layout &layout, const db::Cell &cell, std::set<db::cell_index_type> &called)
|
||||
{
|
||||
// don't delete proxies - they are deleted later when the layout is cleaned
|
||||
for (db::Cell::child_cell_iterator cc = cell.begin_child_cells (); ! cc.at_end (); ++cc) {
|
||||
if (called.find (*cc) == called.end () && !layout.cell (*cc).is_proxy ()) {
|
||||
called.insert (*cc);
|
||||
collect_cells_to_delete (layout, layout.cell (*cc), called);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
validate_cell_path (const db::Layout &layout, lay::LayoutView::cell_path_type &path)
|
||||
{
|
||||
for (size_t i = 0; i < path.size (); ++i) {
|
||||
|
||||
if (! layout.is_valid_cell_index (path [i])) {
|
||||
|
||||
if (layout.is_valid_cell_index (path.back ())) {
|
||||
// use a stub path
|
||||
path.erase (path.begin (), --path.end ());
|
||||
} else {
|
||||
// strip everything that is not valid
|
||||
path.erase (path.begin () + i, path.end ());
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
LayoutViewFunctions::LayoutViewFunctions (db::Manager *manager, LayoutView *view)
|
||||
: lay::Plugin (view), mp_view (view), mp_manager (manager)
|
||||
{
|
||||
@@ -493,18 +528,7 @@ LayoutViewFunctions::cm_cell_replace ()
|
||||
|
||||
view ()->commit ();
|
||||
|
||||
// If one of the cells in the path was deleted, establish a valid path
|
||||
|
||||
bool needs_update = false;
|
||||
for (size_t i = cell_path.size (); i > 0; ) {
|
||||
--i;
|
||||
if (! layout.is_valid_cell_index (cell_path [i])) {
|
||||
cell_path.erase (cell_path.begin () + i, cell_path.end ());
|
||||
needs_update = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (needs_update) {
|
||||
if (validate_cell_path (layout, cell_path)) {
|
||||
view ()->select_cell (cell_path, cv_index);
|
||||
}
|
||||
|
||||
@@ -613,36 +637,13 @@ LayoutViewFunctions::cm_cell_convert_to_static ()
|
||||
|
||||
view ()->commit ();
|
||||
|
||||
// If one of the cells in the path was deleted, establish a valid path
|
||||
|
||||
bool needs_update = false;
|
||||
for (size_t i = cell_path.size (); i > 0; ) {
|
||||
--i;
|
||||
if (! layout.is_valid_cell_index (cell_path [i])) {
|
||||
cell_path.erase (cell_path.begin () + i, cell_path.end ());
|
||||
needs_update = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (needs_update) {
|
||||
if (validate_cell_path (layout, cell_path)) {
|
||||
view ()->select_cell (cell_path, cv_index);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
collect_cells_to_delete (const db::Layout &layout, const db::Cell &cell, std::set<db::cell_index_type> &called)
|
||||
{
|
||||
// don't delete proxies - they are deleted later when the layout is cleaned
|
||||
for (db::Cell::child_cell_iterator cc = cell.begin_child_cells (); ! cc.at_end (); ++cc) {
|
||||
if (called.find (*cc) == called.end () && !layout.cell (*cc).is_proxy ()) {
|
||||
called.insert (*cc);
|
||||
collect_cells_to_delete (layout, layout.cell (*cc), called);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
LayoutViewFunctions::cm_cell_delete ()
|
||||
{
|
||||
@@ -704,18 +705,7 @@ LayoutViewFunctions::cm_cell_delete ()
|
||||
|
||||
view ()->commit ();
|
||||
|
||||
// If one of the cells in the path was deleted, establish a valid path
|
||||
|
||||
bool needs_update = false;
|
||||
for (size_t i = cell_path.size (); i > 0; ) {
|
||||
--i;
|
||||
if (! layout.is_valid_cell_index (cell_path [i])) {
|
||||
cell_path.erase (cell_path.begin () + i, cell_path.end ());
|
||||
needs_update = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (needs_update) {
|
||||
if (validate_cell_path (layout, cell_path)) {
|
||||
view ()->select_cell (cell_path, cv_index);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user