mirror of https://github.com/KLayout/klayout.git
Implemented a solution for #1963 (locking cells)
A cell can be locked using cell.locked = true and unlocked again using cell.locked = false Also, cell.is_locked? can be used to test the locked state. In locked state writing shapes and instances is forbidden and doing so would raise an exception. Also, cells cannot be deleted when locked. However, Layout#clear and Layout#_destroy are always available. Cells can still be renamed, even if locked.
This commit is contained in:
parent
2d5ddd794c
commit
bccf68504f
|
|
@ -93,7 +93,7 @@ Cell::box_type Cell::ms_empty_box = Cell::box_type ();
|
|||
Cell::Cell (cell_index_type ci, db::Layout &l)
|
||||
: db::Object (l.manager ()),
|
||||
m_cell_index (ci), mp_layout (&l), m_instances (this), m_prop_id (0), m_hier_levels (0),
|
||||
m_bbox_needs_update (false), m_ghost_cell (false),
|
||||
m_bbox_needs_update (false), m_locked (false), m_ghost_cell (false),
|
||||
mp_last (0), mp_next (0)
|
||||
{
|
||||
// .. nothing yet
|
||||
|
|
@ -125,6 +125,7 @@ Cell::operator= (const Cell &d)
|
|||
}
|
||||
|
||||
m_ghost_cell = d.m_ghost_cell;
|
||||
m_locked = d.m_locked;
|
||||
m_instances = d.m_instances;
|
||||
m_bbox = d.m_bbox;
|
||||
m_bboxes = d.m_bboxes;
|
||||
|
|
@ -138,6 +139,7 @@ Cell::operator= (const Cell &d)
|
|||
|
||||
Cell::~Cell ()
|
||||
{
|
||||
m_locked = false;
|
||||
clear_shapes ();
|
||||
}
|
||||
|
||||
|
|
@ -180,6 +182,8 @@ Cell::empty () const
|
|||
void
|
||||
Cell::clear (unsigned int index)
|
||||
{
|
||||
check_locked ();
|
||||
|
||||
shapes_map::iterator s = m_shapes_map.find(index);
|
||||
if (s != m_shapes_map.end() && ! s->second.empty ()) {
|
||||
mp_layout->invalidate_bboxes (index); // HINT: must come before the change is done!
|
||||
|
|
@ -191,6 +195,8 @@ Cell::clear (unsigned int index)
|
|||
void
|
||||
Cell::clear (unsigned int index, unsigned int types)
|
||||
{
|
||||
check_locked ();
|
||||
|
||||
shapes_map::iterator s = m_shapes_map.find(index);
|
||||
if (s != m_shapes_map.end() && ! s->second.empty ()) {
|
||||
mp_layout->invalidate_bboxes (index); // HINT: must come before the change is done!
|
||||
|
|
@ -241,6 +247,8 @@ Cell::index_of_shapes (const Cell::shapes_type *shapes) const
|
|||
void
|
||||
Cell::clear_shapes ()
|
||||
{
|
||||
check_locked ();
|
||||
|
||||
mp_layout->invalidate_bboxes (std::numeric_limits<unsigned int>::max ()); // HINT: must come before the change is done!
|
||||
clear_shapes_no_invalidate ();
|
||||
}
|
||||
|
|
@ -345,6 +353,8 @@ Cell::update_bbox (unsigned int layers)
|
|||
void
|
||||
Cell::copy (unsigned int src, unsigned int dest)
|
||||
{
|
||||
check_locked ();
|
||||
|
||||
if (src != dest) {
|
||||
shapes (dest).insert (shapes (src));
|
||||
} else {
|
||||
|
|
@ -359,6 +369,8 @@ Cell::copy (unsigned int src, unsigned int dest)
|
|||
void
|
||||
Cell::copy (unsigned int src, unsigned int dest, unsigned int types)
|
||||
{
|
||||
check_locked ();
|
||||
|
||||
if (src != dest) {
|
||||
shapes (dest).insert (shapes (src), types);
|
||||
} else {
|
||||
|
|
@ -373,6 +385,8 @@ Cell::copy (unsigned int src, unsigned int dest, unsigned int types)
|
|||
void
|
||||
Cell::move (unsigned int src, unsigned int dest)
|
||||
{
|
||||
check_locked ();
|
||||
|
||||
if (src != dest) {
|
||||
copy (src, dest);
|
||||
clear (src);
|
||||
|
|
@ -382,6 +396,8 @@ Cell::move (unsigned int src, unsigned int dest)
|
|||
void
|
||||
Cell::move (unsigned int src, unsigned int dest, unsigned int types)
|
||||
{
|
||||
check_locked ();
|
||||
|
||||
if (src != dest) {
|
||||
copy (src, dest, types);
|
||||
clear (src, types);
|
||||
|
|
@ -391,6 +407,8 @@ Cell::move (unsigned int src, unsigned int dest, unsigned int types)
|
|||
void
|
||||
Cell::swap (unsigned int i1, unsigned int i2)
|
||||
{
|
||||
check_locked ();
|
||||
|
||||
if (i1 != i2) {
|
||||
|
||||
if (manager () && manager ()->transacting ()) {
|
||||
|
|
@ -784,6 +802,14 @@ Cell::set_name (const std::string &name)
|
|||
layout ()->rename_cell (cell_index (), name.c_str ());
|
||||
}
|
||||
|
||||
void
|
||||
Cell::check_locked () const
|
||||
{
|
||||
if (m_locked) {
|
||||
throw tl::Exception (tl::to_string (tr ("Cell '%s' cannot be modified as it is locked")), get_basic_name ());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Cell::copy_shapes (const db::Cell &source_cell, const db::LayerMapping &layer_mapping)
|
||||
{
|
||||
|
|
@ -800,6 +826,8 @@ Cell::copy_shapes (const db::Cell &source_cell, const db::LayerMapping &layer_ma
|
|||
throw tl::Exception (tl::to_string (tr ("Source cell does not reside in a layout")));
|
||||
}
|
||||
|
||||
check_locked ();
|
||||
|
||||
if (target_layout != source_layout) {
|
||||
db::PropertyMapper pm (target_layout, source_layout);
|
||||
db::ICplxTrans trans (source_layout->dbu () / target_layout->dbu ());
|
||||
|
|
@ -824,6 +852,8 @@ Cell::copy_shapes (const db::Cell &source_cell)
|
|||
throw tl::Exception (tl::to_string (tr ("Cell does not reside in a layout")));
|
||||
}
|
||||
|
||||
check_locked ();
|
||||
|
||||
if (target_layout != source_cell.layout ()) {
|
||||
if (! source_cell.layout ()) {
|
||||
throw tl::Exception (tl::to_string (tr ("Source cell does not reside in a layout")));
|
||||
|
|
@ -848,6 +878,8 @@ Cell::copy_instances (const db::Cell &source_cell)
|
|||
throw tl::Exception (tl::to_string (tr ("Cells do not reside in the same layout")));
|
||||
}
|
||||
|
||||
check_locked ();
|
||||
|
||||
for (db::Cell::const_iterator i = source_cell.begin (); ! i.at_end (); ++i) {
|
||||
insert (*i);
|
||||
}
|
||||
|
|
@ -869,6 +901,8 @@ Cell::copy_tree (const db::Cell &source_cell)
|
|||
throw tl::Exception (tl::to_string (tr ("Source cell does not reside in a layout")));
|
||||
}
|
||||
|
||||
check_locked ();
|
||||
|
||||
db::ICplxTrans trans (source_layout->dbu () / target_layout->dbu ());
|
||||
|
||||
db::CellMapping cm;
|
||||
|
|
@ -900,6 +934,8 @@ Cell::copy_tree_shapes (const db::Cell &source_cell, const db::CellMapping &cm)
|
|||
throw tl::Exception (tl::to_string (tr ("Source cell does not reside in a layout")));
|
||||
}
|
||||
|
||||
check_locked ();
|
||||
|
||||
db::ICplxTrans trans (source_layout->dbu () / target_layout->dbu ());
|
||||
|
||||
db::LayerMapping lm;
|
||||
|
|
@ -926,6 +962,8 @@ Cell::copy_tree_shapes (const db::Cell &source_cell, const db::CellMapping &cm,
|
|||
throw tl::Exception (tl::to_string (tr ("Source cell does not reside in a layout")));
|
||||
}
|
||||
|
||||
check_locked ();
|
||||
|
||||
db::ICplxTrans trans (source_layout->dbu () / target_layout->dbu ());
|
||||
|
||||
std::vector <db::cell_index_type> source_cells;
|
||||
|
|
@ -949,6 +987,8 @@ Cell::move_shapes (db::Cell &source_cell, const db::LayerMapping &layer_mapping)
|
|||
throw tl::Exception (tl::to_string (tr ("Source cell does not reside in a layout")));
|
||||
}
|
||||
|
||||
check_locked ();
|
||||
|
||||
if (target_layout != source_layout) {
|
||||
db::PropertyMapper pm (target_layout, source_layout);
|
||||
db::ICplxTrans trans (source_layout->dbu () / target_layout->dbu ());
|
||||
|
|
@ -975,6 +1015,8 @@ Cell::move_shapes (db::Cell &source_cell)
|
|||
throw tl::Exception (tl::to_string (tr ("Cell does not reside in a layout")));
|
||||
}
|
||||
|
||||
check_locked ();
|
||||
|
||||
if (target_layout != source_cell.layout ()) {
|
||||
if (! source_cell.layout ()) {
|
||||
throw tl::Exception (tl::to_string (tr ("Source cell does not reside in a layout")));
|
||||
|
|
@ -1000,6 +1042,8 @@ Cell::move_instances (db::Cell &source_cell)
|
|||
throw tl::Exception (tl::to_string (tr ("Cells do not reside in the same layout")));
|
||||
}
|
||||
|
||||
check_locked ();
|
||||
|
||||
for (db::Cell::const_iterator i = source_cell.begin (); ! i.at_end (); ++i) {
|
||||
insert (*i);
|
||||
}
|
||||
|
|
@ -1023,6 +1067,8 @@ Cell::move_tree (db::Cell &source_cell)
|
|||
throw tl::Exception (tl::to_string (tr ("Source cell does not reside in a layout")));
|
||||
}
|
||||
|
||||
check_locked ();
|
||||
|
||||
db::PropertyMapper pm (target_layout, source_layout);
|
||||
db::ICplxTrans trans (source_layout->dbu () / target_layout->dbu ());
|
||||
|
||||
|
|
@ -1057,6 +1103,8 @@ Cell::move_tree_shapes (db::Cell &source_cell, const db::CellMapping &cm)
|
|||
throw tl::Exception (tl::to_string (tr ("Source cell does not reside in a layout")));
|
||||
}
|
||||
|
||||
check_locked ();
|
||||
|
||||
db::PropertyMapper pm (target_layout, source_layout);
|
||||
db::ICplxTrans trans (source_layout->dbu () / target_layout->dbu ());
|
||||
|
||||
|
|
@ -1084,6 +1132,8 @@ Cell::move_tree_shapes (db::Cell &source_cell, const db::CellMapping &cm, const
|
|||
throw tl::Exception (tl::to_string (tr ("Source cell does not reside in a layout")));
|
||||
}
|
||||
|
||||
check_locked ();
|
||||
|
||||
db::PropertyMapper pm (target_layout, source_layout);
|
||||
db::ICplxTrans trans (source_layout->dbu () / target_layout->dbu ());
|
||||
|
||||
|
|
|
|||
|
|
@ -832,6 +832,13 @@ public:
|
|||
*/
|
||||
virtual void update (ImportLayerMapping * /*layer_mapping*/ = 0) { }
|
||||
|
||||
/**
|
||||
* @brief Checks if the cell is locked
|
||||
*
|
||||
* This method throws an exception if the cell is locked.
|
||||
*/
|
||||
void check_locked () const;
|
||||
|
||||
/**
|
||||
* @brief Tell, if this cell is a proxy cell
|
||||
*
|
||||
|
|
@ -903,6 +910,27 @@ public:
|
|||
m_ghost_cell = g;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets a value indicating whether the cell is locked
|
||||
*
|
||||
* A locked cell cannot be modified in terms of instances or shapes.
|
||||
* The name of a locked cell can be changed though.
|
||||
*/
|
||||
bool is_locked () const
|
||||
{
|
||||
return m_locked;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets the locked state of the cell
|
||||
*
|
||||
* See \is_locked for details about locked state.
|
||||
*/
|
||||
void set_locked (bool f)
|
||||
{
|
||||
m_locked = f;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns a value indicating whether the cell is empty
|
||||
*
|
||||
|
|
@ -1076,8 +1104,9 @@ private:
|
|||
db::properties_id_type m_prop_id;
|
||||
|
||||
// packed fields
|
||||
unsigned int m_hier_levels : 30;
|
||||
unsigned int m_hier_levels : 29;
|
||||
bool m_bbox_needs_update : 1;
|
||||
bool m_locked : 1;
|
||||
bool m_ghost_cell : 1;
|
||||
|
||||
static box_type ms_empty_box;
|
||||
|
|
|
|||
|
|
@ -1035,8 +1035,10 @@ Instances::layout () const
|
|||
void
|
||||
Instances::invalidate_insts ()
|
||||
{
|
||||
if (cell ()) {
|
||||
cell ()->invalidate_insts ();
|
||||
db::Cell *cp = cell ();
|
||||
if (cp) {
|
||||
cp->check_locked ();
|
||||
cp->invalidate_insts ();
|
||||
}
|
||||
|
||||
set_instance_by_cell_index_needs_made (true);
|
||||
|
|
|
|||
|
|
@ -873,6 +873,7 @@ Layout::delete_cells (const std::set<cell_index_type> &cells_to_delete)
|
|||
std::set <cell_index_type> pcs;
|
||||
for (std::set<cell_index_type>::const_iterator c = cells_to_delete.begin (); c != cells_to_delete.end (); ++c) {
|
||||
const db::Cell &cref = cell (*c);
|
||||
cref.check_locked ();
|
||||
for (db::Cell::parent_cell_iterator pc = cref.begin_parent_cells (); pc != cref.end_parent_cells (); ++pc) {
|
||||
pcs.insert (*pc);
|
||||
}
|
||||
|
|
@ -950,6 +951,7 @@ void
|
|||
Layout::delete_cell (cell_index_type id)
|
||||
{
|
||||
db::Cell &cref = cell (id);
|
||||
cref.check_locked ();
|
||||
|
||||
std::vector <cell_index_type> pcs;
|
||||
for (db::Cell::parent_cell_iterator pc = cref.begin_parent_cells (); pc != cref.end_parent_cells (); ++pc) {
|
||||
|
|
@ -1140,6 +1142,8 @@ Layout::flatten (const db::Cell &source_cell, db::Cell &target_cell, const db::I
|
|||
void
|
||||
Layout::flatten (db::Cell &cell_to_flatten, int levels, bool prune)
|
||||
{
|
||||
cell_to_flatten.check_locked ();
|
||||
|
||||
std::set<db::cell_index_type> direct_children;
|
||||
if (prune) {
|
||||
// save direct children
|
||||
|
|
|
|||
|
|
@ -297,12 +297,16 @@ Shapes::array_repository () const
|
|||
void
|
||||
Shapes::invalidate_state ()
|
||||
{
|
||||
db::Cell *cp = cell ();
|
||||
if (cp) {
|
||||
cp->check_locked ();
|
||||
}
|
||||
if (! is_dirty ()) {
|
||||
set_dirty (true);
|
||||
if (layout () && cell ()) {
|
||||
unsigned int index = cell ()->index_of_shapes (this);
|
||||
if (cp && cp->layout ()) {
|
||||
unsigned int index = cp->index_of_shapes (this);
|
||||
if (index != std::numeric_limits<unsigned int>::max ()) {
|
||||
layout ()->invalidate_bboxes (index);
|
||||
cp->layout ()->invalidate_bboxes (index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2923,6 +2923,28 @@ Class<db::Cell> decl_Cell ("db", "Cell",
|
|||
"\n"
|
||||
"@return A list of cell indices.\n"
|
||||
) +
|
||||
gsi::method ("is_locked?", &db::Cell::is_locked,
|
||||
"@brief Gets a value indicating whether the cell is locked\n"
|
||||
"\n"
|
||||
"Locked cells cannot be modified in terms of instances (children) and shapes. "
|
||||
"Locked cells can still be renamed, but cannot be deleted or cleared.\n"
|
||||
"Among other things, these features are disabled too: layer operations, copy of instances or shapes, "
|
||||
"flattening or pruning.\n"
|
||||
"\n"
|
||||
"However, wiping the layout entirely with \\Layout#clear is always possible, even if cells are locked.\n"
|
||||
"\n"
|
||||
"Use \\locked= to set the locked state of the cell.\n"
|
||||
"\n"
|
||||
"The lock feature has been introduced in version 0.29.11."
|
||||
) +
|
||||
gsi::method ("locked=", &db::Cell::set_locked, gsi::arg ("l"),
|
||||
"@brief Locks or unlocks the cell\n"
|
||||
"\n"
|
||||
"Set this predicate to 'true' to lock the cell and to 'false' to unlock it.\n"
|
||||
"See \\is_locked? for details about the lock feature.\n"
|
||||
"\n"
|
||||
"The lock feature has been introduced in version 0.29.11."
|
||||
) +
|
||||
gsi::method ("bbox", (const db::Cell::box_type &(db::Cell::*) () const) &db::Cell::bbox,
|
||||
"@brief Gets the bounding box of the cell\n"
|
||||
"\n"
|
||||
|
|
|
|||
|
|
@ -124,6 +124,230 @@ class DBCellTests_TestClass < TestBase
|
|||
|
||||
end
|
||||
|
||||
# locking
|
||||
def test_4
|
||||
|
||||
ly = RBA::Layout::new
|
||||
top = ly.create_cell("TOP")
|
||||
other = ly.create_cell("OTHER")
|
||||
child = ly.create_cell("CHILD")
|
||||
|
||||
l1 = ly.layer(1, 0)
|
||||
l2 = ly.layer(2, 0)
|
||||
shape = top.shapes(l1).insert(RBA::Box::new(0, 0, 100, 200))
|
||||
inst = top.insert(RBA::CellInstArray::new(child, RBA::Trans::new(RBA::Vector::new(100, 200))))
|
||||
other.insert(RBA::CellInstArray::new(child, RBA::Trans::new(RBA::Vector::new(10, 20))))
|
||||
|
||||
assert_equal(top.is_locked?, false)
|
||||
top.locked = false
|
||||
assert_equal(top.is_locked?, false)
|
||||
top.locked = true
|
||||
assert_equal(top.is_locked?, true)
|
||||
|
||||
# rename is still possible
|
||||
top.name = "TOP2"
|
||||
|
||||
# instances of the cell can still be created
|
||||
toptop = ly.create_cell("TOPTOP")
|
||||
toptop.insert(RBA::CellInstArray::new(top, RBA::Trans::new))
|
||||
assert_equal(top.each_parent_inst.to_a[0].child_inst.to_s, "cell_index=0 r0 0,0")
|
||||
|
||||
begin
|
||||
# forbidden now
|
||||
top.shapes(l2).insert(RBA::Box::new(0, 0, 100, 200))
|
||||
assert_equal(true, false)
|
||||
rescue => ex
|
||||
assert_equal(ex.to_s, "Cell 'TOP2' cannot be modified as it is locked in Shapes::insert")
|
||||
end
|
||||
|
||||
begin
|
||||
# forbidden now
|
||||
shape.box = RBA::Box::new(1, 2, 101, 202)
|
||||
assert_equal(true, false)
|
||||
rescue => ex
|
||||
assert_equal(ex.to_s, "Cell 'TOP2' cannot be modified as it is locked in Shape::box=")
|
||||
end
|
||||
|
||||
begin
|
||||
# forbidden now
|
||||
shape.prop_id = 1
|
||||
assert_equal(true, false)
|
||||
rescue => ex
|
||||
assert_equal(ex.to_s, "Cell 'TOP2' cannot be modified as it is locked in Shape::prop_id=")
|
||||
end
|
||||
|
||||
begin
|
||||
# forbidden now
|
||||
shape.polygon = RBA::Polygon::new(RBA::Box::new(0, 0, 200, 100))
|
||||
assert_equal(true, false)
|
||||
rescue => ex
|
||||
assert_equal(ex.to_s, "Cell 'TOP2' cannot be modified as it is locked in Shape::polygon=")
|
||||
end
|
||||
|
||||
begin
|
||||
# forbidden now
|
||||
inst.cell_index = other.cell_index
|
||||
assert_equal(true, false)
|
||||
rescue => ex
|
||||
assert_equal(ex.to_s, "Cell 'TOP2' cannot be modified as it is locked in Instance::cell_index=")
|
||||
end
|
||||
|
||||
begin
|
||||
# forbidden now
|
||||
inst.prop_id = 1
|
||||
assert_equal(true, false)
|
||||
rescue => ex
|
||||
assert_equal(ex.to_s, "Cell 'TOP2' cannot be modified as it is locked in Instance::prop_id=")
|
||||
end
|
||||
|
||||
begin
|
||||
# also forbidden
|
||||
top.insert(RBA::CellInstArray::new(child, RBA::Trans::new))
|
||||
assert_equal(true, false)
|
||||
rescue => ex
|
||||
assert_equal(ex.to_s, "Cell 'TOP2' cannot be modified as it is locked in Cell::insert")
|
||||
end
|
||||
|
||||
begin
|
||||
# clear is forbidding
|
||||
top.clear
|
||||
assert_equal(true, false)
|
||||
rescue => ex
|
||||
assert_equal(ex.to_s, "Cell 'TOP2' cannot be modified as it is locked in Cell::clear")
|
||||
end
|
||||
|
||||
begin
|
||||
# clear layer is forbidden
|
||||
top.shapes(l1).clear
|
||||
assert_equal(true, false)
|
||||
rescue => ex
|
||||
assert_equal(ex.to_s, "Cell 'TOP2' cannot be modified as it is locked in Shapes::clear")
|
||||
end
|
||||
|
||||
begin
|
||||
# clear layer is forbidden
|
||||
top.clear(l1)
|
||||
assert_equal(true, false)
|
||||
rescue => ex
|
||||
assert_equal(ex.to_s, "Cell 'TOP2' cannot be modified as it is locked in Cell::clear")
|
||||
end
|
||||
|
||||
begin
|
||||
# layer copy is forbidden
|
||||
top.copy(l1, l2)
|
||||
assert_equal(true, false)
|
||||
rescue => ex
|
||||
assert_equal(ex.to_s, "Cell 'TOP2' cannot be modified as it is locked in Cell::copy")
|
||||
end
|
||||
|
||||
begin
|
||||
# layer move is forbidden
|
||||
top.move(l1, l2)
|
||||
assert_equal(true, false)
|
||||
rescue => ex
|
||||
assert_equal(ex.to_s, "Cell 'TOP2' cannot be modified as it is locked in Cell::move")
|
||||
end
|
||||
|
||||
begin
|
||||
# layer swap is forbidden
|
||||
top.swap(l1, l2)
|
||||
assert_equal(true, false)
|
||||
rescue => ex
|
||||
assert_equal(ex.to_s, "Cell 'TOP2' cannot be modified as it is locked in Cell::swap")
|
||||
end
|
||||
|
||||
begin
|
||||
# copy_instances is forbidden
|
||||
top.copy_instances(other)
|
||||
assert_equal(true, false)
|
||||
rescue => ex
|
||||
assert_equal(ex.to_s, "Cell 'TOP2' cannot be modified as it is locked in Cell::copy_instances")
|
||||
end
|
||||
|
||||
begin
|
||||
# move_instances is forbidden
|
||||
top.move_instances(other)
|
||||
assert_equal(true, false)
|
||||
rescue => ex
|
||||
assert_equal(ex.to_s, "Cell 'TOP2' cannot be modified as it is locked in Cell::move_instances")
|
||||
end
|
||||
|
||||
begin
|
||||
# copy_tree is forbidden
|
||||
top.copy_tree(other)
|
||||
assert_equal(true, false)
|
||||
rescue => ex
|
||||
assert_equal(ex.to_s, "Cell 'TOP2' cannot be modified as it is locked in Cell::copy_tree")
|
||||
end
|
||||
|
||||
begin
|
||||
# move_tree is forbidden
|
||||
top.move_tree(other)
|
||||
assert_equal(true, false)
|
||||
rescue => ex
|
||||
assert_equal(ex.to_s, "Cell 'TOP2' cannot be modified as it is locked in Cell::move_tree")
|
||||
end
|
||||
|
||||
begin
|
||||
# copy_shapes is forbidden
|
||||
top.copy_shapes(other)
|
||||
assert_equal(true, false)
|
||||
rescue => ex
|
||||
assert_equal(ex.to_s, "Cell 'TOP2' cannot be modified as it is locked in Cell::copy_shapes")
|
||||
end
|
||||
|
||||
begin
|
||||
# move_shapes is forbidden
|
||||
top.move_shapes(other)
|
||||
assert_equal(true, false)
|
||||
rescue => ex
|
||||
assert_equal(ex.to_s, "Cell 'TOP2' cannot be modified as it is locked in Cell::move_shapes")
|
||||
end
|
||||
|
||||
begin
|
||||
# flatten is forbidden
|
||||
top.flatten(true)
|
||||
assert_equal(true, false)
|
||||
rescue => ex
|
||||
assert_equal(ex.to_s, "Cell 'TOP2' cannot be modified as it is locked in Cell::flatten")
|
||||
end
|
||||
|
||||
begin
|
||||
# cell cannot be deleted
|
||||
top.delete
|
||||
assert_equal(true, false)
|
||||
rescue => ex
|
||||
assert_equal(ex.to_s, "Cell 'TOP2' cannot be modified as it is locked in Cell::delete")
|
||||
end
|
||||
|
||||
# locked attribute is copied
|
||||
ly2 = ly.dup
|
||||
assert_equal(ly2.cell("TOP2").is_locked?, true)
|
||||
|
||||
begin
|
||||
# cell cannot be deleted
|
||||
ly2.cell("TOP2").delete
|
||||
assert_equal(true, false)
|
||||
rescue => ex
|
||||
assert_equal(ex.to_s, "Cell 'TOP2' cannot be modified as it is locked in Cell::delete")
|
||||
end
|
||||
|
||||
# clear and _destroy is always possible
|
||||
ly2.clear
|
||||
|
||||
ly2 = ly.dup
|
||||
ly2._destroy
|
||||
|
||||
# resetting the locked flag enables things again (not all tested here)
|
||||
top.locked = false
|
||||
|
||||
inst.cell_index = other.cell_index
|
||||
top.shapes(l2).insert(RBA::Box::new(0, 0, 100, 200))
|
||||
shape.box = RBA::Box::new(1, 2, 101, 202)
|
||||
top.delete
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
load("test_epilogue.rb")
|
||||
|
|
|
|||
Loading…
Reference in New Issue