mirror of https://github.com/KLayout/klayout.git
Merge pull request #865 from KLayout/issue-864
Fixed #864 (Shapes#copy_shapes does not support undo/redo)
This commit is contained in:
commit
054bfa3be4
|
|
@ -333,21 +333,13 @@ void
|
||||||
Cell::copy (unsigned int src, unsigned int dest)
|
Cell::copy (unsigned int src, unsigned int dest)
|
||||||
{
|
{
|
||||||
if (src != dest) {
|
if (src != dest) {
|
||||||
db::Shapes &dest_shapes = shapes (dest);
|
shapes (dest).insert (shapes (src));
|
||||||
db::Cell::shape_iterator src_shape = begin (src, db::Shapes::shape_iterator::All);
|
|
||||||
while (! src_shape.at_end ()) {
|
|
||||||
dest_shapes.insert (*src_shape);
|
|
||||||
++src_shape;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// When duplicating the layer, first create a copy to avoid problems with non-stable containers
|
// When duplicating the layer, first create a copy to avoid problems with non-stable containers
|
||||||
// Hint: using the assignment and not the copy ctor does not copy the db::Manager association.
|
// Hint: using the assignment and not the copy ctor does not copy the db::Manager association.
|
||||||
db::Shapes shape_copy;
|
db::Shapes shape_copy;
|
||||||
shape_copy = shapes (src);
|
shape_copy = shapes (src);
|
||||||
db::Shapes &dest_shapes = shapes (dest);
|
shapes (dest).insert (shape_copy);
|
||||||
for (db::Cell::shape_iterator src_shape = shape_copy.begin (db::Shapes::shape_iterator::All); ! src_shape.at_end (); ++src_shape) {
|
|
||||||
dest_shapes.insert (*src_shape);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -837,6 +837,14 @@ Instance::bbox () const
|
||||||
// -------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------
|
||||||
// Instances implementation
|
// Instances implementation
|
||||||
|
|
||||||
|
static void
|
||||||
|
check_is_editable_for_undo_redo (const Instances *instances)
|
||||||
|
{
|
||||||
|
if (! instances->is_editable ()) {
|
||||||
|
throw tl::Exception (tl::to_string (tr ("No undo/redo support on non-editable instance lists")));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Instances::Instances (cell_type *cell)
|
Instances::Instances (cell_type *cell)
|
||||||
: mp_cell (cell)
|
: mp_cell (cell)
|
||||||
{
|
{
|
||||||
|
|
@ -957,6 +965,10 @@ Instances::erase_positions (Tag tag, ET editable_tag, I first, I last)
|
||||||
if (mp_cell) {
|
if (mp_cell) {
|
||||||
mp_cell->invalidate_insts (); // HINT: must come before the change is done!
|
mp_cell->invalidate_insts (); // HINT: must come before the change is done!
|
||||||
if (mp_cell->manager () && mp_cell->manager ()->transacting ()) {
|
if (mp_cell->manager () && mp_cell->manager ()->transacting ()) {
|
||||||
|
check_is_editable_for_undo_redo (this);
|
||||||
|
if (! is_editable ()) {
|
||||||
|
throw tl::Exception (tl::to_string (tr ("No undo/redo support for non-editable instance lists in 'erase_positions'")));
|
||||||
|
}
|
||||||
mp_cell->manager ()->queue (mp_cell, new db::InstOp<typename Tag::object_type, ET> (false /*not insert*/, first, last, true /*dummy*/));
|
mp_cell->manager ()->queue (mp_cell, new db::InstOp<typename Tag::object_type, ET> (false /*not insert*/, first, last, true /*dummy*/));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -973,6 +985,7 @@ Instances::insert (const InstArray &inst)
|
||||||
|
|
||||||
if (mp_cell) {
|
if (mp_cell) {
|
||||||
if (mp_cell->manager () && mp_cell->manager ()->transacting ()) {
|
if (mp_cell->manager () && mp_cell->manager ()->transacting ()) {
|
||||||
|
check_is_editable_for_undo_redo (this);
|
||||||
if (editable) {
|
if (editable) {
|
||||||
mp_cell->manager ()->queue (mp_cell, new db::InstOp<InstArray, InstancesEditableTag> (true /*insert*/, inst));
|
mp_cell->manager ()->queue (mp_cell, new db::InstOp<InstArray, InstancesEditableTag> (true /*insert*/, inst));
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -999,6 +1012,7 @@ Instances::insert (I from, I to)
|
||||||
|
|
||||||
if (mp_cell) {
|
if (mp_cell) {
|
||||||
if (mp_cell->manager () && mp_cell->manager ()->transacting ()) {
|
if (mp_cell->manager () && mp_cell->manager ()->transacting ()) {
|
||||||
|
check_is_editable_for_undo_redo (this);
|
||||||
mp_cell->manager ()->queue (mp_cell, new db::InstOp<typename it_traits::value_type, ET> (true /*insert*/, from, to));
|
mp_cell->manager ()->queue (mp_cell, new db::InstOp<typename it_traits::value_type, ET> (true /*insert*/, from, to));
|
||||||
}
|
}
|
||||||
mp_cell->invalidate_insts ();
|
mp_cell->invalidate_insts ();
|
||||||
|
|
@ -1049,6 +1063,7 @@ Instances::replace (const InstArray *replace, const InstArray &with)
|
||||||
{
|
{
|
||||||
if (mp_cell) {
|
if (mp_cell) {
|
||||||
if (mp_cell->manager () && mp_cell->manager ()->transacting ()) {
|
if (mp_cell->manager () && mp_cell->manager ()->transacting ()) {
|
||||||
|
check_is_editable_for_undo_redo (this);
|
||||||
if (is_editable ()) {
|
if (is_editable ()) {
|
||||||
mp_cell->manager ()->queue (mp_cell, new db::InstOp<InstArray, InstancesEditableTag> (false /*not insert*/, *replace));
|
mp_cell->manager ()->queue (mp_cell, new db::InstOp<InstArray, InstancesEditableTag> (false /*not insert*/, *replace));
|
||||||
mp_cell->manager ()->queue (mp_cell, new db::InstOp<InstArray, InstancesEditableTag> (true /*insert*/, with));
|
mp_cell->manager ()->queue (mp_cell, new db::InstOp<InstArray, InstancesEditableTag> (true /*insert*/, with));
|
||||||
|
|
@ -1138,6 +1153,7 @@ Instances::erase_inst_by_iter (Tag tag, ET editable_tag, I iter)
|
||||||
if (mp_cell) {
|
if (mp_cell) {
|
||||||
mp_cell->invalidate_insts ();
|
mp_cell->invalidate_insts ();
|
||||||
if (mp_cell->manager () && mp_cell->manager ()->transacting ()) {
|
if (mp_cell->manager () && mp_cell->manager ()->transacting ()) {
|
||||||
|
check_is_editable_for_undo_redo (this);
|
||||||
mp_cell->manager ()->queue (mp_cell, new db::InstOp<typename Tag::object_type, ET> (false /*not insert*/, *iter));
|
mp_cell->manager ()->queue (mp_cell, new db::InstOp<typename Tag::object_type, ET> (false /*not insert*/, *iter));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1152,6 +1168,7 @@ Instances::erase_inst_by_tag (Tag tag, ET editable_tag, const typename Tag::obje
|
||||||
if (mp_cell) {
|
if (mp_cell) {
|
||||||
mp_cell->invalidate_insts ();
|
mp_cell->invalidate_insts ();
|
||||||
if (mp_cell->manager () && mp_cell->manager ()->transacting ()) {
|
if (mp_cell->manager () && mp_cell->manager ()->transacting ()) {
|
||||||
|
check_is_editable_for_undo_redo (this);
|
||||||
mp_cell->manager ()->queue (mp_cell, new db::InstOp<typename Tag::object_type, ET> (false /*not insert*/, obj));
|
mp_cell->manager ()->queue (mp_cell, new db::InstOp<typename Tag::object_type, ET> (false /*not insert*/, obj));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1183,6 +1200,7 @@ Instances::clear_insts (ET editable_tag)
|
||||||
if (mp_cell) {
|
if (mp_cell) {
|
||||||
mp_cell->invalidate_insts ();
|
mp_cell->invalidate_insts ();
|
||||||
if (mp_cell->manager () && mp_cell->manager ()->transacting ()) {
|
if (mp_cell->manager () && mp_cell->manager ()->transacting ()) {
|
||||||
|
check_is_editable_for_undo_redo (this);
|
||||||
const Instances *const_this = this;
|
const Instances *const_this = this;
|
||||||
if (! const_this->inst_tree (cell_inst_array_type::tag (), editable_tag).empty ()) {
|
if (! const_this->inst_tree (cell_inst_array_type::tag (), editable_tag).empty ()) {
|
||||||
mp_cell->manager ()->queue (mp_cell, new db::InstOp<cell_inst_array_type, ET> (false /*not insert*/, const_this->inst_tree (cell_inst_array_type::tag (), editable_tag).begin (), const_this->inst_tree (cell_inst_array_type::tag (), editable_tag).end ()));
|
mp_cell->manager ()->queue (mp_cell, new db::InstOp<cell_inst_array_type, ET> (false /*not insert*/, const_this->inst_tree (cell_inst_array_type::tag (), editable_tag).begin (), const_this->inst_tree (cell_inst_array_type::tag (), editable_tag).end ()));
|
||||||
|
|
@ -1588,6 +1606,7 @@ void Instances::apply_op (const Op &op, ET editable_tag)
|
||||||
if (mp_cell) {
|
if (mp_cell) {
|
||||||
mp_cell->invalidate_insts ();
|
mp_cell->invalidate_insts ();
|
||||||
if (mp_cell->manager () && mp_cell->manager ()->transacting ()) {
|
if (mp_cell->manager () && mp_cell->manager ()->transacting ()) {
|
||||||
|
check_is_editable_for_undo_redo (this);
|
||||||
transacting = true;
|
transacting = true;
|
||||||
if (has_insts) {
|
if (has_insts) {
|
||||||
mp_cell->manager ()->queue (mp_cell, new db::InstOp<cell_inst_array_type, ET> (false /*not insert*/, const_this->inst_tree (cell_inst_array_type::tag (), editable_tag).begin (), const_this->inst_tree (cell_inst_array_type::tag (), editable_tag).end ()));
|
mp_cell->manager ()->queue (mp_cell, new db::InstOp<cell_inst_array_type, ET> (false /*not insert*/, const_this->inst_tree (cell_inst_array_type::tag (), editable_tag).begin (), const_this->inst_tree (cell_inst_array_type::tag (), editable_tag).end ()));
|
||||||
|
|
|
||||||
|
|
@ -131,6 +131,50 @@ layer_op<Sh, StableTag>::erase (Shapes *shapes)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------------------
|
||||||
|
// FullLayerOp implementation
|
||||||
|
|
||||||
|
void
|
||||||
|
FullLayerOp::insert (Shapes *shapes)
|
||||||
|
{
|
||||||
|
for (tl::vector<LayerBase *>::iterator l = shapes->get_layers ().end (); l != shapes->get_layers ().begin (); ) {
|
||||||
|
|
||||||
|
--l;
|
||||||
|
|
||||||
|
if (*l == mp_layer) {
|
||||||
|
|
||||||
|
return;
|
||||||
|
|
||||||
|
} else if ((*l)->is_same_type (mp_layer)) {
|
||||||
|
|
||||||
|
delete (*l);
|
||||||
|
*l = mp_layer;
|
||||||
|
m_owns_layer = false;
|
||||||
|
shapes->invalidate_state ();
|
||||||
|
return;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
shapes->get_layers ().push_back (mp_layer);
|
||||||
|
shapes->invalidate_state ();
|
||||||
|
m_owns_layer = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
FullLayerOp::erase (Shapes *shapes)
|
||||||
|
{
|
||||||
|
for (tl::vector<LayerBase *>::iterator l = shapes->get_layers ().begin (); l != shapes->get_layers ().end (); ++l) {
|
||||||
|
if (*l == mp_layer) {
|
||||||
|
shapes->get_layers ().erase (l);
|
||||||
|
shapes->invalidate_state ();
|
||||||
|
m_owns_layer = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------------
|
||||||
// Shapes implementation
|
// Shapes implementation
|
||||||
|
|
||||||
|
|
@ -155,11 +199,17 @@ Shapes::layout () const
|
||||||
return c ? c->layout () : 0;
|
return c ? c->layout () : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Shapes::check_is_editable_for_undo_redo () const
|
||||||
|
{
|
||||||
|
if (! is_editable ()) {
|
||||||
|
throw tl::Exception (tl::to_string (tr ("No undo/redo support on non-editable shape lists")));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Shapes::insert (const Shapes &d)
|
Shapes::insert (const Shapes &d)
|
||||||
{
|
{
|
||||||
// no undo support for this currently
|
|
||||||
tl_assert (! manager () || ! manager ()->transacting ());
|
|
||||||
do_insert (d);
|
do_insert (d);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -175,10 +225,18 @@ Shapes::do_insert (const Shapes &d)
|
||||||
|
|
||||||
// both shape containers reside in the same repository space - simply copy
|
// both shape containers reside in the same repository space - simply copy
|
||||||
if (m_layers.empty ()) {
|
if (m_layers.empty ()) {
|
||||||
|
|
||||||
m_layers.reserve (d.m_layers.size ());
|
m_layers.reserve (d.m_layers.size ());
|
||||||
for (tl::vector<LayerBase *>::const_iterator l = d.m_layers.begin (); l != d.m_layers.end (); ++l) {
|
for (tl::vector<LayerBase *>::const_iterator l = d.m_layers.begin (); l != d.m_layers.end (); ++l) {
|
||||||
m_layers.push_back ((*l)->clone (this, manager ()));
|
m_layers.push_back ((*l)->clone ());
|
||||||
|
if (manager () && manager ()->transacting ()) {
|
||||||
|
check_is_editable_for_undo_redo ();
|
||||||
|
manager ()->queue (this, new FullLayerOp (true, m_layers.back ()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
invalidate_state ();
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
for (tl::vector<LayerBase *>::const_iterator l = d.m_layers.begin (); l != d.m_layers.end (); ++l) {
|
for (tl::vector<LayerBase *>::const_iterator l = d.m_layers.begin (); l != d.m_layers.end (); ++l) {
|
||||||
(*l)->insert_into (this);
|
(*l)->insert_into (this);
|
||||||
|
|
@ -939,12 +997,22 @@ void
|
||||||
Shapes::clear ()
|
Shapes::clear ()
|
||||||
{
|
{
|
||||||
if (!m_layers.empty ()) {
|
if (!m_layers.empty ()) {
|
||||||
for (tl::vector<LayerBase *>::const_iterator l = m_layers.begin (); l != m_layers.end (); ++l) {
|
|
||||||
(*l)->clear (this, manager ());
|
for (tl::vector<LayerBase *>::const_iterator l = m_layers.end (); l != m_layers.begin (); ) {
|
||||||
delete *l;
|
// because the undo stack will do a push, we need to remove layers from the back (this is the last undo
|
||||||
|
// element to be executed)
|
||||||
|
--l;
|
||||||
|
if (manager () && manager ()->transacting ()) {
|
||||||
|
check_is_editable_for_undo_redo ();
|
||||||
|
manager ()->queue (this, new FullLayerOp (false, (*l)));
|
||||||
|
} else {
|
||||||
|
delete *l;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
invalidate_state (); // HINT: must come before the change is done!
|
invalidate_state (); // HINT: must come before the change is done!
|
||||||
m_layers.clear ();
|
m_layers.clear ();
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1104,6 +1172,7 @@ Shapes::replace_prop_id (const Sh *pos, db::properties_id_type prop_id)
|
||||||
throw tl::Exception (tl::to_string (tr ("Function 'replace' is permitted only in editable mode")));
|
throw tl::Exception (tl::to_string (tr ("Function 'replace' is permitted only in editable mode")));
|
||||||
}
|
}
|
||||||
if (manager () && manager ()->transacting ()) {
|
if (manager () && manager ()->transacting ()) {
|
||||||
|
check_is_editable_for_undo_redo ();
|
||||||
db::layer_op<Sh, db::stable_layer_tag>::queue_or_append (manager (), this, false /*not insert*/, *pos);
|
db::layer_op<Sh, db::stable_layer_tag>::queue_or_append (manager (), this, false /*not insert*/, *pos);
|
||||||
}
|
}
|
||||||
invalidate_state (); // HINT: must come before the change is done!
|
invalidate_state (); // HINT: must come before the change is done!
|
||||||
|
|
@ -1123,6 +1192,7 @@ Shapes::replace_prop_id_iter (typename db::object_tag<Sh>, const Iter &iter, db:
|
||||||
}
|
}
|
||||||
|
|
||||||
if (manager () && manager ()->transacting ()) {
|
if (manager () && manager ()->transacting ()) {
|
||||||
|
check_is_editable_for_undo_redo ();
|
||||||
db::layer_op<Sh, db::stable_layer_tag>::queue_or_append (manager (), this, false /*not insert*/, *iter);
|
db::layer_op<Sh, db::stable_layer_tag>::queue_or_append (manager (), this, false /*not insert*/, *iter);
|
||||||
}
|
}
|
||||||
db::object_with_properties <Sh> wp (*iter, prop_id);
|
db::object_with_properties <Sh> wp (*iter, prop_id);
|
||||||
|
|
@ -1190,6 +1260,7 @@ Shapes::replace_member_with_props (typename db::object_tag<Sh> tag, const shape_
|
||||||
// simple replace case
|
// simple replace case
|
||||||
|
|
||||||
if (manager () && manager ()->transacting ()) {
|
if (manager () && manager ()->transacting ()) {
|
||||||
|
check_is_editable_for_undo_redo ();
|
||||||
db::layer_op<Sh, db::stable_layer_tag>::queue_or_append (manager (), this, false /*not insert*/, *ref.basic_ptr (tag));
|
db::layer_op<Sh, db::stable_layer_tag>::queue_or_append (manager (), this, false /*not insert*/, *ref.basic_ptr (tag));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1214,6 +1285,7 @@ Shapes::replace_member_with_props (typename db::object_tag<Sh> tag, const shape_
|
||||||
if (! ref.with_props ()) {
|
if (! ref.with_props ()) {
|
||||||
|
|
||||||
if (manager () && manager ()->transacting ()) {
|
if (manager () && manager ()->transacting ()) {
|
||||||
|
check_is_editable_for_undo_redo ();
|
||||||
db::layer_op<Sh, db::stable_layer_tag>::queue_or_append (manager (), this, false /*not insert*/, *ref.basic_ptr (tag));
|
db::layer_op<Sh, db::stable_layer_tag>::queue_or_append (manager (), this, false /*not insert*/, *ref.basic_ptr (tag));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1234,6 +1306,7 @@ Shapes::replace_member_with_props (typename db::object_tag<Sh> tag, const shape_
|
||||||
get_layer<Sh, db::stable_layer_tag> ().replace (ref.basic_iter (tag), sh);
|
get_layer<Sh, db::stable_layer_tag> ().replace (ref.basic_iter (tag), sh);
|
||||||
|
|
||||||
if (manager () && manager ()->transacting ()) {
|
if (manager () && manager ()->transacting ()) {
|
||||||
|
check_is_editable_for_undo_redo ();
|
||||||
db::layer_op<Sh, db::stable_layer_tag>::queue_or_append (manager (), this, true /*insert*/, sh);
|
db::layer_op<Sh, db::stable_layer_tag>::queue_or_append (manager (), this, true /*insert*/, sh);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1242,6 +1315,7 @@ Shapes::replace_member_with_props (typename db::object_tag<Sh> tag, const shape_
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
if (manager () && manager ()->transacting ()) {
|
if (manager () && manager ()->transacting ()) {
|
||||||
|
check_is_editable_for_undo_redo ();
|
||||||
db::layer_op<db::object_with_properties<Sh>, db::stable_layer_tag>::queue_or_append (manager (), this, false /*not insert*/, *ref.basic_ptr (typename db::object_with_properties<Sh>::tag ()));
|
db::layer_op<db::object_with_properties<Sh>, db::stable_layer_tag>::queue_or_append (manager (), this, false /*not insert*/, *ref.basic_ptr (typename db::object_with_properties<Sh>::tag ()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -486,8 +486,8 @@ public:
|
||||||
virtual size_t size () const = 0;
|
virtual size_t size () const = 0;
|
||||||
virtual bool empty () const = 0;
|
virtual bool empty () const = 0;
|
||||||
virtual void sort () = 0;
|
virtual void sort () = 0;
|
||||||
virtual void clear (Shapes *target, db::Manager *manager) = 0;
|
virtual LayerBase *clone () const = 0;
|
||||||
virtual LayerBase *clone (Shapes *target, db::Manager *manager) const = 0;
|
virtual bool is_same_type (const LayerBase *other) const = 0;
|
||||||
virtual void translate_into (Shapes *target, GenericRepository &rep, ArrayRepository &array_rep) const = 0;
|
virtual void translate_into (Shapes *target, GenericRepository &rep, ArrayRepository &array_rep) const = 0;
|
||||||
virtual void translate_into (Shapes *target, GenericRepository &rep, ArrayRepository &array_rep, pm_delegate_type &pm) const = 0;
|
virtual void translate_into (Shapes *target, GenericRepository &rep, ArrayRepository &array_rep, pm_delegate_type &pm) const = 0;
|
||||||
virtual void transform_into (Shapes *target, const Trans &trans, GenericRepository &rep, ArrayRepository &array_rep) const = 0;
|
virtual void transform_into (Shapes *target, const Trans &trans, GenericRepository &rep, ArrayRepository &array_rep) const = 0;
|
||||||
|
|
@ -682,6 +682,8 @@ public:
|
||||||
|
|
||||||
if (manager () && manager ()->transacting ()) {
|
if (manager () && manager ()->transacting ()) {
|
||||||
|
|
||||||
|
check_is_editable_for_undo_redo ();
|
||||||
|
|
||||||
tl::ident_map<db::properties_id_type> pm;
|
tl::ident_map<db::properties_id_type> pm;
|
||||||
|
|
||||||
// for undo support iterate over the elements
|
// for undo support iterate over the elements
|
||||||
|
|
@ -721,6 +723,8 @@ public:
|
||||||
|
|
||||||
if (manager () && manager ()->transacting ()) {
|
if (manager () && manager ()->transacting ()) {
|
||||||
|
|
||||||
|
check_is_editable_for_undo_redo ();
|
||||||
|
|
||||||
// for undo support iterate over the elements
|
// for undo support iterate over the elements
|
||||||
for (ShapeIterator s = d.begin (ShapeIterator::All); ! s.at_end (); ++s) {
|
for (ShapeIterator s = d.begin (ShapeIterator::All); ! s.at_end (); ++s) {
|
||||||
insert (*s, trans, pm);
|
insert (*s, trans, pm);
|
||||||
|
|
@ -760,6 +764,8 @@ public:
|
||||||
|
|
||||||
if (manager () && manager ()->transacting ()) {
|
if (manager () && manager ()->transacting ()) {
|
||||||
|
|
||||||
|
check_is_editable_for_undo_redo ();
|
||||||
|
|
||||||
// for undo support iterate over the elements
|
// for undo support iterate over the elements
|
||||||
for (ShapeIterator s = d.begin (ShapeIterator::All); ! s.at_end (); ++s) {
|
for (ShapeIterator s = d.begin (ShapeIterator::All); ! s.at_end (); ++s) {
|
||||||
insert (*s, pm);
|
insert (*s, pm);
|
||||||
|
|
@ -806,6 +812,7 @@ public:
|
||||||
shape_type insert (const Sh &sh)
|
shape_type insert (const Sh &sh)
|
||||||
{
|
{
|
||||||
if (manager () && manager ()->transacting ()) {
|
if (manager () && manager ()->transacting ()) {
|
||||||
|
check_is_editable_for_undo_redo ();
|
||||||
if (is_editable ()) {
|
if (is_editable ()) {
|
||||||
db::layer_op<Sh, db::stable_layer_tag>::queue_or_append (manager (), this, true /*insert*/, sh);
|
db::layer_op<Sh, db::stable_layer_tag>::queue_or_append (manager (), this, true /*insert*/, sh);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -849,6 +856,7 @@ public:
|
||||||
|
|
||||||
// insert the array as a whole in non-editable mode
|
// insert the array as a whole in non-editable mode
|
||||||
if (manager () && manager ()->transacting ()) {
|
if (manager () && manager ()->transacting ()) {
|
||||||
|
check_is_editable_for_undo_redo ();
|
||||||
db::layer_op<db::array<Obj, Trans>, db::unstable_layer_tag>::queue_or_append (manager (), this, true /*insert*/, arr);
|
db::layer_op<db::array<Obj, Trans>, db::unstable_layer_tag>::queue_or_append (manager (), this, true /*insert*/, arr);
|
||||||
}
|
}
|
||||||
invalidate_state (); // HINT: must come before the change is done!
|
invalidate_state (); // HINT: must come before the change is done!
|
||||||
|
|
@ -886,6 +894,7 @@ public:
|
||||||
|
|
||||||
// insert the array as a whole in non-editable mode
|
// insert the array as a whole in non-editable mode
|
||||||
if (manager () && manager ()->transacting ()) {
|
if (manager () && manager ()->transacting ()) {
|
||||||
|
check_is_editable_for_undo_redo ();
|
||||||
db::layer_op< db::object_with_properties< db::array<Obj, Trans> >, db::unstable_layer_tag>::queue_or_append (manager (), this, true /*insert*/, arr);
|
db::layer_op< db::object_with_properties< db::array<Obj, Trans> >, db::unstable_layer_tag>::queue_or_append (manager (), this, true /*insert*/, arr);
|
||||||
}
|
}
|
||||||
invalidate_state (); // HINT: must come before the change is done!
|
invalidate_state (); // HINT: must come before the change is done!
|
||||||
|
|
@ -906,6 +915,7 @@ public:
|
||||||
{
|
{
|
||||||
typedef typename std::iterator_traits <Iter>::value_type value_type;
|
typedef typename std::iterator_traits <Iter>::value_type value_type;
|
||||||
if (manager () && manager ()->transacting ()) {
|
if (manager () && manager ()->transacting ()) {
|
||||||
|
check_is_editable_for_undo_redo ();
|
||||||
if (is_editable ()) {
|
if (is_editable ()) {
|
||||||
db::layer_op<value_type, db::stable_layer_tag>::queue_or_append (manager (), this, true /*insert*/, from, to);
|
db::layer_op<value_type, db::stable_layer_tag>::queue_or_append (manager (), this, true /*insert*/, from, to);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -1001,6 +1011,7 @@ public:
|
||||||
throw tl::Exception (tl::to_string (tr ("Function 'erase' is permitted only in editable mode")));
|
throw tl::Exception (tl::to_string (tr ("Function 'erase' is permitted only in editable mode")));
|
||||||
}
|
}
|
||||||
if (manager () && manager ()->transacting ()) {
|
if (manager () && manager ()->transacting ()) {
|
||||||
|
check_is_editable_for_undo_redo ();
|
||||||
db::layer_op<typename Tag::object_type, StableTag>::queue_or_append (manager (), this, false /*not insert*/, *pos);
|
db::layer_op<typename Tag::object_type, StableTag>::queue_or_append (manager (), this, false /*not insert*/, *pos);
|
||||||
}
|
}
|
||||||
invalidate_state (); // HINT: must come before the change is done!
|
invalidate_state (); // HINT: must come before the change is done!
|
||||||
|
|
@ -1064,6 +1075,7 @@ public:
|
||||||
throw tl::Exception (tl::to_string (tr ("Function 'erase' is permitted only in editable mode")));
|
throw tl::Exception (tl::to_string (tr ("Function 'erase' is permitted only in editable mode")));
|
||||||
}
|
}
|
||||||
if (manager () && manager ()->transacting ()) {
|
if (manager () && manager ()->transacting ()) {
|
||||||
|
check_is_editable_for_undo_redo ();
|
||||||
db::layer_op<typename Tag::object_type, StableTag>::queue_or_append (manager (), this, false /*not insert*/, from, to);
|
db::layer_op<typename Tag::object_type, StableTag>::queue_or_append (manager (), this, false /*not insert*/, from, to);
|
||||||
}
|
}
|
||||||
invalidate_state (); // HINT: must come before the change is done!
|
invalidate_state (); // HINT: must come before the change is done!
|
||||||
|
|
@ -1090,6 +1102,7 @@ public:
|
||||||
throw tl::Exception (tl::to_string (tr ("Function 'erase' is permitted only in editable mode")));
|
throw tl::Exception (tl::to_string (tr ("Function 'erase' is permitted only in editable mode")));
|
||||||
}
|
}
|
||||||
if (manager () && manager ()->transacting ()) {
|
if (manager () && manager ()->transacting ()) {
|
||||||
|
check_is_editable_for_undo_redo ();
|
||||||
db::layer_op<typename Tag::object_type, StableTag>::queue_or_append (manager (), this, false /*not insert*/, first, last, true /*dummy*/);
|
db::layer_op<typename Tag::object_type, StableTag>::queue_or_append (manager (), this, false /*not insert*/, first, last, true /*dummy*/);
|
||||||
}
|
}
|
||||||
invalidate_state (); // HINT: must come before the change is done!
|
invalidate_state (); // HINT: must come before the change is done!
|
||||||
|
|
@ -1480,12 +1493,20 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class ShapeIterator;
|
friend class ShapeIterator;
|
||||||
|
friend class FullLayerOp;
|
||||||
|
|
||||||
tl::vector<LayerBase *> m_layers;
|
tl::vector<LayerBase *> m_layers;
|
||||||
db::Cell *mp_cell; // HINT: contains "dirty" in bit 0 and "editable" in bit 1
|
db::Cell *mp_cell; // HINT: contains "dirty" in bit 0 and "editable" in bit 1
|
||||||
|
|
||||||
void invalidate_state ();
|
void invalidate_state ();
|
||||||
void do_insert (const Shapes &d);
|
void do_insert (const Shapes &d);
|
||||||
|
void check_is_editable_for_undo_redo () const;
|
||||||
|
|
||||||
|
// gets the layers array
|
||||||
|
tl::vector<LayerBase *> &get_layers ()
|
||||||
|
{
|
||||||
|
return m_layers;
|
||||||
|
}
|
||||||
|
|
||||||
// extract dirty flag from mp_cell
|
// extract dirty flag from mp_cell
|
||||||
bool is_dirty () const
|
bool is_dirty () const
|
||||||
|
|
@ -1604,6 +1625,7 @@ private:
|
||||||
for (typename Array::iterator a = arr.begin (); ! a.at_end (); ++a) {
|
for (typename Array::iterator a = arr.begin (); ! a.at_end (); ++a) {
|
||||||
res_wp_type obj_wp (*a * arr.object (), arr.properties_id ());
|
res_wp_type obj_wp (*a * arr.object (), arr.properties_id ());
|
||||||
if (manager () && manager ()->transacting ()) {
|
if (manager () && manager ()->transacting ()) {
|
||||||
|
check_is_editable_for_undo_redo ();
|
||||||
db::layer_op<res_wp_type, db::stable_layer_tag>::queue_or_append (manager (), this, true /*insert*/, obj_wp);
|
db::layer_op<res_wp_type, db::stable_layer_tag>::queue_or_append (manager (), this, true /*insert*/, obj_wp);
|
||||||
}
|
}
|
||||||
l.insert (obj_wp);
|
l.insert (obj_wp);
|
||||||
|
|
@ -1618,6 +1640,7 @@ private:
|
||||||
db::layer<ResType, db::stable_layer_tag> &l = get_layer<ResType, db::stable_layer_tag> ();
|
db::layer<ResType, db::stable_layer_tag> &l = get_layer<ResType, db::stable_layer_tag> ();
|
||||||
for (typename Array::iterator a = arr.begin (); ! a.at_end (); ++a) {
|
for (typename Array::iterator a = arr.begin (); ! a.at_end (); ++a) {
|
||||||
if (manager () && manager ()->transacting ()) {
|
if (manager () && manager ()->transacting ()) {
|
||||||
|
check_is_editable_for_undo_redo ();
|
||||||
db::layer_op<ResType, db::stable_layer_tag>::queue_or_append (manager (), this, true /*insert*/, *a * arr.object ());
|
db::layer_op<ResType, db::stable_layer_tag>::queue_or_append (manager (), this, true /*insert*/, *a * arr.object ());
|
||||||
}
|
}
|
||||||
l.insert (*a * arr.object ());
|
l.insert (*a * arr.object ());
|
||||||
|
|
@ -1743,6 +1766,51 @@ private:
|
||||||
void erase (Shapes *shapes);
|
void erase (Shapes *shapes);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class FullLayerOp
|
||||||
|
: public LayerOpBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FullLayerOp (bool insert, LayerBase *layer)
|
||||||
|
: m_insert (insert), mp_layer (layer), m_owns_layer (! insert)
|
||||||
|
{
|
||||||
|
// .. nothing yet ..
|
||||||
|
}
|
||||||
|
|
||||||
|
~FullLayerOp ()
|
||||||
|
{
|
||||||
|
if (m_owns_layer) {
|
||||||
|
delete mp_layer;
|
||||||
|
mp_layer = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void undo (Shapes *shapes)
|
||||||
|
{
|
||||||
|
if (m_insert) {
|
||||||
|
erase (shapes);
|
||||||
|
} else {
|
||||||
|
insert (shapes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void redo (Shapes *shapes)
|
||||||
|
{
|
||||||
|
if (m_insert) {
|
||||||
|
insert (shapes);
|
||||||
|
} else {
|
||||||
|
erase (shapes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool m_insert;
|
||||||
|
LayerBase *mp_layer;
|
||||||
|
bool m_owns_layer;
|
||||||
|
|
||||||
|
void insert (Shapes *shapes);
|
||||||
|
void erase (Shapes *shapes);
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace db
|
} // namespace db
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -752,24 +752,11 @@ inline unsigned int iterator_type_mask (db::object_tag< db::object_with_properti
|
||||||
return iterator_type_mask (typename Sh::tag ());
|
return iterator_type_mask (typename Sh::tag ());
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Sh, class StableTag>
|
|
||||||
void
|
|
||||||
layer_class<Sh, StableTag>::clear (Shapes *target, db::Manager *manager)
|
|
||||||
{
|
|
||||||
if (manager && manager->transacting ()) {
|
|
||||||
manager->queue (target, new db::layer_op<Sh, StableTag> (false /*not insert*/, m_layer.begin (), m_layer.end ()));
|
|
||||||
}
|
|
||||||
m_layer.clear ();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Sh, class StableTag>
|
template <class Sh, class StableTag>
|
||||||
LayerBase *
|
LayerBase *
|
||||||
layer_class<Sh, StableTag>::clone (Shapes *target, db::Manager *manager) const
|
layer_class<Sh, StableTag>::clone () const
|
||||||
{
|
{
|
||||||
layer_class<Sh, StableTag> *r = new layer_class<Sh, StableTag> ();
|
layer_class<Sh, StableTag> *r = new layer_class<Sh, StableTag> ();
|
||||||
if (manager && manager->transacting ()) {
|
|
||||||
manager->queue (target, new db::layer_op<Sh, StableTag> (true /*insert*/, m_layer.begin (), m_layer.end ()));
|
|
||||||
}
|
|
||||||
r->m_layer = m_layer;
|
r->m_layer = m_layer;
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
@ -877,7 +864,6 @@ layer_class<Sh, StableTag>::deref_and_transform_into (Shapes *target, const Tran
|
||||||
{
|
{
|
||||||
deref_and_transform_into_shapes deref_op (target);
|
deref_and_transform_into_shapes deref_op (target);
|
||||||
for (typename layer_type::iterator s = m_layer.begin (); s != m_layer.end (); ++s) {
|
for (typename layer_type::iterator s = m_layer.begin (); s != m_layer.end (); ++s) {
|
||||||
|
|
||||||
deref_op (*s, trans, pm);
|
deref_op (*s, trans, pm);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -141,8 +141,12 @@ public:
|
||||||
m_layer.sort ();
|
m_layer.sort ();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void clear (Shapes *target, db::Manager *manager);
|
virtual bool is_same_type (const LayerBase *other) const
|
||||||
virtual LayerBase *clone (Shapes *target, db::Manager *manager) const;
|
{
|
||||||
|
return dynamic_cast<const layer_class<Sh, StableTag> *> (other);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual LayerBase *clone () const;
|
||||||
virtual void translate_into (Shapes *target, GenericRepository &rep, ArrayRepository &array_rep) const;
|
virtual void translate_into (Shapes *target, GenericRepository &rep, ArrayRepository &array_rep) const;
|
||||||
virtual void translate_into (Shapes *target, GenericRepository &rep, ArrayRepository &array_rep, pm_delegate_type &pm) const;
|
virtual void translate_into (Shapes *target, GenericRepository &rep, ArrayRepository &array_rep, pm_delegate_type &pm) const;
|
||||||
virtual void transform_into (Shapes *target, const Trans &trans, GenericRepository &rep, ArrayRepository &array_rep) const;
|
virtual void transform_into (Shapes *target, const Trans &trans, GenericRepository &rep, ArrayRepository &array_rep) const;
|
||||||
|
|
|
||||||
|
|
@ -344,6 +344,7 @@ Shapes::erase_shape_by_tag_ws (Tag /*tag*/, StableTag /*stable_tag*/, const shap
|
||||||
db::layer<typename Tag::object_type, StableTag> &l = get_layer<typename Tag::object_type, StableTag> ();
|
db::layer<typename Tag::object_type, StableTag> &l = get_layer<typename Tag::object_type, StableTag> ();
|
||||||
typename db::layer<typename Tag::object_type, StableTag>::iterator i = iterator_from_shape (l, shape);
|
typename db::layer<typename Tag::object_type, StableTag>::iterator i = iterator_from_shape (l, shape);
|
||||||
if (manager () && manager ()->transacting ()) {
|
if (manager () && manager ()->transacting ()) {
|
||||||
|
check_is_editable_for_undo_redo ();
|
||||||
db::layer_op<typename Tag::object_type, StableTag>::queue_or_append (manager (), this, false /*not insert*/, *i);
|
db::layer_op<typename Tag::object_type, StableTag>::queue_or_append (manager (), this, false /*not insert*/, *i);
|
||||||
}
|
}
|
||||||
invalidate_state (); // HINT: must come before the change is done!
|
invalidate_state (); // HINT: must come before the change is done!
|
||||||
|
|
@ -356,6 +357,7 @@ Shapes::erase_shape_by_tag_ws (Tag /*tag*/, StableTag /*stable_tag*/, const shap
|
||||||
db::layer<swp_type, StableTag> &l = get_layer<swp_type, StableTag> ();
|
db::layer<swp_type, StableTag> &l = get_layer<swp_type, StableTag> ();
|
||||||
typename db::layer<swp_type, StableTag>::iterator i = iterator_from_shape (l, shape);
|
typename db::layer<swp_type, StableTag>::iterator i = iterator_from_shape (l, shape);
|
||||||
if (manager () && manager ()->transacting ()) {
|
if (manager () && manager ()->transacting ()) {
|
||||||
|
check_is_editable_for_undo_redo ();
|
||||||
db::layer_op<swp_type, StableTag>::queue_or_append (manager (), this, false /*not insert*/, *i);
|
db::layer_op<swp_type, StableTag>::queue_or_append (manager (), this, false /*not insert*/, *i);
|
||||||
}
|
}
|
||||||
invalidate_state (); // HINT: must come before the change is done!
|
invalidate_state (); // HINT: must come before the change is done!
|
||||||
|
|
|
||||||
|
|
@ -246,12 +246,7 @@ static void insert_iter_with_trans (db::Shapes *sh, const db::RecursiveShapeIter
|
||||||
|
|
||||||
static void insert_shapes (db::Shapes *sh, const db::Shapes &s)
|
static void insert_shapes (db::Shapes *sh, const db::Shapes &s)
|
||||||
{
|
{
|
||||||
// NOTE: if the source (r) is from the same layout than the shapes live in, we better
|
sh->insert (s);
|
||||||
// lock the layout against updates while inserting
|
|
||||||
db::LayoutLocker locker (sh->layout ());
|
|
||||||
for (db::Shapes::shape_iterator i = s.begin (db::ShapeIterator::All); !i.at_end(); ++i) {
|
|
||||||
sh->insert (*i);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void insert_shapes_with_flags (db::Shapes *sh, const db::Shapes &s, unsigned int flags)
|
static void insert_shapes_with_flags (db::Shapes *sh, const db::Shapes &s, unsigned int flags)
|
||||||
|
|
|
||||||
|
|
@ -557,9 +557,13 @@ TEST(5)
|
||||||
EXPECT_EQ (l2s (l), "begin_lib 0.001\nbegin_cell {LIBCELL}\nbox 1 0 {0 0} {100 200}\nend_cell\nend_lib\n");
|
EXPECT_EQ (l2s (l), "begin_lib 0.001\nbegin_cell {LIBCELL}\nbox 1 0 {0 0} {100 200}\nend_cell\nend_lib\n");
|
||||||
|
|
||||||
// switch to another LIBCELL, this time using layer 2/0
|
// switch to another LIBCELL, this time using layer 2/0
|
||||||
m.transaction ("switch_to_b");
|
if (l.is_editable ()) {
|
||||||
l.set_technology_name ("B");
|
m.transaction ("switch_to_b");
|
||||||
m.commit ();
|
l.set_technology_name ("B");
|
||||||
|
m.commit ();
|
||||||
|
} else {
|
||||||
|
l.set_technology_name ("B");
|
||||||
|
}
|
||||||
|
|
||||||
EXPECT_EQ (l.technology_name (), "B");
|
EXPECT_EQ (l.technology_name (), "B");
|
||||||
cell = &l.cell (l.cell_by_name ("LIBCELL").second);
|
cell = &l.cell (l.cell_by_name ("LIBCELL").second);
|
||||||
|
|
@ -609,9 +613,13 @@ TEST(6)
|
||||||
info.pcell_parameters ["npoints"] = tl::Variant (8);
|
info.pcell_parameters ["npoints"] = tl::Variant (8);
|
||||||
info.pcell_parameters ["layer"] = tl::Variant (db::LayerProperties (1, 0));
|
info.pcell_parameters ["layer"] = tl::Variant (db::LayerProperties (1, 0));
|
||||||
|
|
||||||
m.transaction ("import");
|
if (l.is_editable ()) {
|
||||||
|
m.transaction ("import");
|
||||||
|
}
|
||||||
cell = l.recover_proxy (info);
|
cell = l.recover_proxy (info);
|
||||||
m.commit ();
|
if (l.is_editable ()) {
|
||||||
|
m.commit ();
|
||||||
|
}
|
||||||
EXPECT_EQ (cell->get_qualified_name (), "Basic.CIRCLE");
|
EXPECT_EQ (cell->get_qualified_name (), "Basic.CIRCLE");
|
||||||
EXPECT_EQ (cell->get_basic_name (), "CIRCLE");
|
EXPECT_EQ (cell->get_basic_name (), "CIRCLE");
|
||||||
EXPECT_EQ (cell->get_display_name (), "Basic.CIRCLE(l=1/0,r=10,n=8)");
|
EXPECT_EQ (cell->get_display_name (), "Basic.CIRCLE(l=1/0,r=10,n=8)");
|
||||||
|
|
@ -622,10 +630,14 @@ TEST(6)
|
||||||
l.get_context_info (cell->cell_index (), info2);
|
l.get_context_info (cell->cell_index (), info2);
|
||||||
info2.pcell_parameters ["actual_radius"] = tl::Variant (5.0);
|
info2.pcell_parameters ["actual_radius"] = tl::Variant (5.0);
|
||||||
|
|
||||||
m.transaction ("modify");
|
if (l.is_editable ()) {
|
||||||
|
m.transaction ("modify");
|
||||||
|
}
|
||||||
db::cell_index_type ci = cell->cell_index ();
|
db::cell_index_type ci = cell->cell_index ();
|
||||||
l.recover_proxy_as (ci, info2);
|
l.recover_proxy_as (ci, info2);
|
||||||
m.commit ();
|
if (l.is_editable ()) {
|
||||||
|
m.commit ();
|
||||||
|
}
|
||||||
cell = &l.cell (ci);
|
cell = &l.cell (ci);
|
||||||
EXPECT_EQ (cell->get_qualified_name (), "Basic.CIRCLE");
|
EXPECT_EQ (cell->get_qualified_name (), "Basic.CIRCLE");
|
||||||
EXPECT_EQ (cell->get_basic_name (), "CIRCLE");
|
EXPECT_EQ (cell->get_basic_name (), "CIRCLE");
|
||||||
|
|
|
||||||
|
|
@ -3235,6 +3235,193 @@ TEST(23)
|
||||||
EXPECT_EQ (shapes_to_string_norm (_this, s2), "edge_pair (0,0;1,1)/(10,10;11,11) #17\n");
|
EXPECT_EQ (shapes_to_string_norm (_this, s2), "edge_pair (0,0;1,1)/(10,10;11,11) #17\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Shape insert and clear and undo/redo
|
||||||
|
TEST(24a)
|
||||||
|
{
|
||||||
|
db::Manager m;
|
||||||
|
db::Shapes s1 (&m, 0, true), s2;
|
||||||
|
|
||||||
|
s2.insert (db::Edge (db::Point (0, 0), db::Point (100, 200)));
|
||||||
|
s2.insert (db::Box (db::Point (0, 0), db::Point (100, 200)));
|
||||||
|
|
||||||
|
m.transaction ("test");
|
||||||
|
EXPECT_EQ (shapes_to_string_norm (_this, s1), "");
|
||||||
|
s1.insert (s2);
|
||||||
|
EXPECT_EQ (shapes_to_string_norm (_this, s1), "box (0,0;100,200) #0\nedge (0,0;100,200) #0\n");
|
||||||
|
m.commit ();
|
||||||
|
|
||||||
|
m.undo ();
|
||||||
|
EXPECT_EQ (shapes_to_string_norm (_this, s1), "");
|
||||||
|
|
||||||
|
m.redo ();
|
||||||
|
EXPECT_EQ (shapes_to_string_norm (_this, s1), "box (0,0;100,200) #0\nedge (0,0;100,200) #0\n");
|
||||||
|
|
||||||
|
m.undo ();
|
||||||
|
s1.insert (db::Box (db::Point (1, 1), db::Point (101, 201)));
|
||||||
|
EXPECT_EQ (shapes_to_string_norm (_this, s1), "box (1,1;101,201) #0\n");
|
||||||
|
|
||||||
|
m.clear ();
|
||||||
|
EXPECT_EQ (shapes_to_string_norm (_this, s1), "box (1,1;101,201) #0\n");
|
||||||
|
|
||||||
|
m.transaction ("test");
|
||||||
|
EXPECT_EQ (shapes_to_string_norm (_this, s1), "box (1,1;101,201) #0\n");
|
||||||
|
s1.insert (s2);
|
||||||
|
EXPECT_EQ (shapes_to_string_norm (_this, s1), "box (0,0;100,200) #0\nbox (1,1;101,201) #0\nedge (0,0;100,200) #0\n");
|
||||||
|
m.commit ();
|
||||||
|
|
||||||
|
m.undo ();
|
||||||
|
EXPECT_EQ (shapes_to_string_norm (_this, s1), "box (1,1;101,201) #0\n");
|
||||||
|
|
||||||
|
m.redo ();
|
||||||
|
EXPECT_EQ (shapes_to_string_norm (_this, s1), "box (0,0;100,200) #0\nbox (1,1;101,201) #0\nedge (0,0;100,200) #0\n");
|
||||||
|
|
||||||
|
m.clear ();
|
||||||
|
EXPECT_EQ (shapes_to_string_norm (_this, s1), "box (0,0;100,200) #0\nbox (1,1;101,201) #0\nedge (0,0;100,200) #0\n");
|
||||||
|
|
||||||
|
m.transaction ("test");
|
||||||
|
EXPECT_EQ (shapes_to_string_norm (_this, s1), "box (0,0;100,200) #0\nbox (1,1;101,201) #0\nedge (0,0;100,200) #0\n");
|
||||||
|
s1.clear ();
|
||||||
|
EXPECT_EQ (shapes_to_string_norm (_this, s1), "");
|
||||||
|
m.commit ();
|
||||||
|
|
||||||
|
m.undo ();
|
||||||
|
EXPECT_EQ (shapes_to_string_norm (_this, s1), "box (0,0;100,200) #0\nbox (1,1;101,201) #0\nedge (0,0;100,200) #0\n");
|
||||||
|
|
||||||
|
m.redo ();
|
||||||
|
EXPECT_EQ (shapes_to_string_norm (_this, s1), "");
|
||||||
|
|
||||||
|
m.clear ();
|
||||||
|
EXPECT_EQ (shapes_to_string_norm (_this, s1), "");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Shape insert and clear and undo/redo - different layers, same layout
|
||||||
|
TEST(24b)
|
||||||
|
{
|
||||||
|
db::Manager m;
|
||||||
|
db::Layout l (true, &m);
|
||||||
|
db::Cell &cell = l.cell (l.add_cell ("top"));
|
||||||
|
l.insert_layer (1);
|
||||||
|
l.insert_layer (2);
|
||||||
|
db::Shapes &s1 = cell.shapes (1);
|
||||||
|
db::Shapes &s2 = cell.shapes (2);
|
||||||
|
|
||||||
|
s2.insert (db::Edge (db::Point (0, 0), db::Point (100, 200)));
|
||||||
|
s2.insert (db::Box (db::Point (0, 0), db::Point (100, 200)));
|
||||||
|
|
||||||
|
m.transaction ("test");
|
||||||
|
EXPECT_EQ (shapes_to_string_norm (_this, s1), "");
|
||||||
|
s1.insert (s2);
|
||||||
|
EXPECT_EQ (shapes_to_string_norm (_this, s1), "box (0,0;100,200) #0\nedge (0,0;100,200) #0\n");
|
||||||
|
m.commit ();
|
||||||
|
|
||||||
|
m.undo ();
|
||||||
|
EXPECT_EQ (shapes_to_string_norm (_this, s1), "");
|
||||||
|
|
||||||
|
m.redo ();
|
||||||
|
EXPECT_EQ (shapes_to_string_norm (_this, s1), "box (0,0;100,200) #0\nedge (0,0;100,200) #0\n");
|
||||||
|
|
||||||
|
m.undo ();
|
||||||
|
s1.insert (db::Box (db::Point (1, 1), db::Point (101, 201)));
|
||||||
|
EXPECT_EQ (shapes_to_string_norm (_this, s1), "box (1,1;101,201) #0\n");
|
||||||
|
|
||||||
|
m.clear ();
|
||||||
|
EXPECT_EQ (shapes_to_string_norm (_this, s1), "box (1,1;101,201) #0\n");
|
||||||
|
|
||||||
|
m.transaction ("test");
|
||||||
|
EXPECT_EQ (shapes_to_string_norm (_this, s1), "box (1,1;101,201) #0\n");
|
||||||
|
s1.insert (s2);
|
||||||
|
EXPECT_EQ (shapes_to_string_norm (_this, s1), "box (0,0;100,200) #0\nbox (1,1;101,201) #0\nedge (0,0;100,200) #0\n");
|
||||||
|
m.commit ();
|
||||||
|
|
||||||
|
m.undo ();
|
||||||
|
EXPECT_EQ (shapes_to_string_norm (_this, s1), "box (1,1;101,201) #0\n");
|
||||||
|
|
||||||
|
m.redo ();
|
||||||
|
EXPECT_EQ (shapes_to_string_norm (_this, s1), "box (0,0;100,200) #0\nbox (1,1;101,201) #0\nedge (0,0;100,200) #0\n");
|
||||||
|
|
||||||
|
m.clear ();
|
||||||
|
EXPECT_EQ (shapes_to_string_norm (_this, s1), "box (0,0;100,200) #0\nbox (1,1;101,201) #0\nedge (0,0;100,200) #0\n");
|
||||||
|
|
||||||
|
m.transaction ("test");
|
||||||
|
EXPECT_EQ (shapes_to_string_norm (_this, s1), "box (0,0;100,200) #0\nbox (1,1;101,201) #0\nedge (0,0;100,200) #0\n");
|
||||||
|
s1.clear ();
|
||||||
|
EXPECT_EQ (shapes_to_string_norm (_this, s1), "");
|
||||||
|
m.commit ();
|
||||||
|
|
||||||
|
m.undo ();
|
||||||
|
EXPECT_EQ (shapes_to_string_norm (_this, s1), "box (0,0;100,200) #0\nbox (1,1;101,201) #0\nedge (0,0;100,200) #0\n");
|
||||||
|
|
||||||
|
m.redo ();
|
||||||
|
EXPECT_EQ (shapes_to_string_norm (_this, s1), "");
|
||||||
|
|
||||||
|
m.clear ();
|
||||||
|
EXPECT_EQ (shapes_to_string_norm (_this, s1), "");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Shape insert and clear and undo/redo - no layout on target
|
||||||
|
TEST(24c)
|
||||||
|
{
|
||||||
|
db::Manager m;
|
||||||
|
db::Layout l;
|
||||||
|
db::Cell &cell = l.cell (l.add_cell ("top"));
|
||||||
|
l.insert_layer (1);
|
||||||
|
l.insert_layer (2);
|
||||||
|
db::Shapes s1 (&m, 0, true);
|
||||||
|
db::Shapes &s2 = cell.shapes (2);
|
||||||
|
|
||||||
|
s2.insert (db::Edge (db::Point (0, 0), db::Point (100, 200)));
|
||||||
|
s2.insert (db::Box (db::Point (0, 0), db::Point (100, 200)));
|
||||||
|
|
||||||
|
m.transaction ("test");
|
||||||
|
EXPECT_EQ (shapes_to_string_norm (_this, s1), "");
|
||||||
|
s1.insert (s2);
|
||||||
|
EXPECT_EQ (shapes_to_string_norm (_this, s1), "box (0,0;100,200) #0\nedge (0,0;100,200) #0\n");
|
||||||
|
m.commit ();
|
||||||
|
|
||||||
|
m.undo ();
|
||||||
|
EXPECT_EQ (shapes_to_string_norm (_this, s1), "");
|
||||||
|
|
||||||
|
m.redo ();
|
||||||
|
EXPECT_EQ (shapes_to_string_norm (_this, s1), "box (0,0;100,200) #0\nedge (0,0;100,200) #0\n");
|
||||||
|
|
||||||
|
m.undo ();
|
||||||
|
s1.insert (db::Box (db::Point (1, 1), db::Point (101, 201)));
|
||||||
|
EXPECT_EQ (shapes_to_string_norm (_this, s1), "box (1,1;101,201) #0\n");
|
||||||
|
|
||||||
|
m.clear ();
|
||||||
|
EXPECT_EQ (shapes_to_string_norm (_this, s1), "box (1,1;101,201) #0\n");
|
||||||
|
|
||||||
|
m.transaction ("test");
|
||||||
|
EXPECT_EQ (shapes_to_string_norm (_this, s1), "box (1,1;101,201) #0\n");
|
||||||
|
s1.insert (s2);
|
||||||
|
EXPECT_EQ (shapes_to_string_norm (_this, s1), "box (0,0;100,200) #0\nbox (1,1;101,201) #0\nedge (0,0;100,200) #0\n");
|
||||||
|
m.commit ();
|
||||||
|
|
||||||
|
m.undo ();
|
||||||
|
EXPECT_EQ (shapes_to_string_norm (_this, s1), "box (1,1;101,201) #0\n");
|
||||||
|
|
||||||
|
m.redo ();
|
||||||
|
EXPECT_EQ (shapes_to_string_norm (_this, s1), "box (0,0;100,200) #0\nbox (1,1;101,201) #0\nedge (0,0;100,200) #0\n");
|
||||||
|
|
||||||
|
m.clear ();
|
||||||
|
EXPECT_EQ (shapes_to_string_norm (_this, s1), "box (0,0;100,200) #0\nbox (1,1;101,201) #0\nedge (0,0;100,200) #0\n");
|
||||||
|
|
||||||
|
m.transaction ("test");
|
||||||
|
EXPECT_EQ (shapes_to_string_norm (_this, s1), "box (0,0;100,200) #0\nbox (1,1;101,201) #0\nedge (0,0;100,200) #0\n");
|
||||||
|
s1.clear ();
|
||||||
|
EXPECT_EQ (shapes_to_string_norm (_this, s1), "");
|
||||||
|
m.commit ();
|
||||||
|
|
||||||
|
m.undo ();
|
||||||
|
EXPECT_EQ (shapes_to_string_norm (_this, s1), "box (0,0;100,200) #0\nbox (1,1;101,201) #0\nedge (0,0;100,200) #0\n");
|
||||||
|
|
||||||
|
m.redo ();
|
||||||
|
EXPECT_EQ (shapes_to_string_norm (_this, s1), "");
|
||||||
|
|
||||||
|
m.clear ();
|
||||||
|
EXPECT_EQ (shapes_to_string_norm (_this, s1), "");
|
||||||
|
}
|
||||||
|
|
||||||
// Bug #107
|
// Bug #107
|
||||||
TEST(100)
|
TEST(100)
|
||||||
{
|
{
|
||||||
|
|
@ -3262,6 +3449,72 @@ TEST(100)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Shape insert and clear and undo/redo - different layouts
|
||||||
|
TEST(24d)
|
||||||
|
{
|
||||||
|
db::Manager m;
|
||||||
|
db::Layout l1 (true, &m);
|
||||||
|
db::Cell &cell1 = l1.cell (l1.add_cell ("top"));
|
||||||
|
l1.insert_layer (1);
|
||||||
|
db::Layout l2 (true, &m);
|
||||||
|
db::Cell &cell2 = l2.cell (l2.add_cell ("top"));
|
||||||
|
l2.insert_layer (2);
|
||||||
|
db::Shapes &s1 = cell1.shapes (1);
|
||||||
|
db::Shapes &s2 = cell2.shapes (2);
|
||||||
|
|
||||||
|
s2.insert (db::Edge (db::Point (0, 0), db::Point (100, 200)));
|
||||||
|
s2.insert (db::Box (db::Point (0, 0), db::Point (100, 200)));
|
||||||
|
|
||||||
|
m.transaction ("test");
|
||||||
|
EXPECT_EQ (shapes_to_string_norm (_this, s1), "");
|
||||||
|
s1.insert (s2);
|
||||||
|
EXPECT_EQ (shapes_to_string_norm (_this, s1), "box (0,0;100,200) #0\nedge (0,0;100,200) #0\n");
|
||||||
|
m.commit ();
|
||||||
|
|
||||||
|
m.undo ();
|
||||||
|
EXPECT_EQ (shapes_to_string_norm (_this, s1), "");
|
||||||
|
|
||||||
|
m.redo ();
|
||||||
|
EXPECT_EQ (shapes_to_string_norm (_this, s1), "box (0,0;100,200) #0\nedge (0,0;100,200) #0\n");
|
||||||
|
|
||||||
|
m.undo ();
|
||||||
|
s1.insert (db::Box (db::Point (1, 1), db::Point (101, 201)));
|
||||||
|
EXPECT_EQ (shapes_to_string_norm (_this, s1), "box (1,1;101,201) #0\n");
|
||||||
|
|
||||||
|
m.clear ();
|
||||||
|
EXPECT_EQ (shapes_to_string_norm (_this, s1), "box (1,1;101,201) #0\n");
|
||||||
|
|
||||||
|
m.transaction ("test");
|
||||||
|
EXPECT_EQ (shapes_to_string_norm (_this, s1), "box (1,1;101,201) #0\n");
|
||||||
|
s1.insert (s2);
|
||||||
|
EXPECT_EQ (shapes_to_string_norm (_this, s1), "box (0,0;100,200) #0\nbox (1,1;101,201) #0\nedge (0,0;100,200) #0\n");
|
||||||
|
m.commit ();
|
||||||
|
|
||||||
|
m.undo ();
|
||||||
|
EXPECT_EQ (shapes_to_string_norm (_this, s1), "box (1,1;101,201) #0\n");
|
||||||
|
|
||||||
|
m.redo ();
|
||||||
|
EXPECT_EQ (shapes_to_string_norm (_this, s1), "box (0,0;100,200) #0\nbox (1,1;101,201) #0\nedge (0,0;100,200) #0\n");
|
||||||
|
|
||||||
|
m.clear ();
|
||||||
|
EXPECT_EQ (shapes_to_string_norm (_this, s1), "box (0,0;100,200) #0\nbox (1,1;101,201) #0\nedge (0,0;100,200) #0\n");
|
||||||
|
|
||||||
|
m.transaction ("test");
|
||||||
|
EXPECT_EQ (shapes_to_string_norm (_this, s1), "box (0,0;100,200) #0\nbox (1,1;101,201) #0\nedge (0,0;100,200) #0\n");
|
||||||
|
s1.clear ();
|
||||||
|
EXPECT_EQ (shapes_to_string_norm (_this, s1), "");
|
||||||
|
m.commit ();
|
||||||
|
|
||||||
|
m.undo ();
|
||||||
|
EXPECT_EQ (shapes_to_string_norm (_this, s1), "box (0,0;100,200) #0\nbox (1,1;101,201) #0\nedge (0,0;100,200) #0\n");
|
||||||
|
|
||||||
|
m.redo ();
|
||||||
|
EXPECT_EQ (shapes_to_string_norm (_this, s1), "");
|
||||||
|
|
||||||
|
m.clear ();
|
||||||
|
EXPECT_EQ (shapes_to_string_norm (_this, s1), "");
|
||||||
|
}
|
||||||
|
|
||||||
// Bug #835
|
// Bug #835
|
||||||
TEST(101)
|
TEST(101)
|
||||||
{
|
{
|
||||||
|
|
@ -3322,3 +3575,4 @@ TEST(101)
|
||||||
const db::Path &qr2_obj = *b.shape_repository ().repository (db::Path::tag ()).begin ();
|
const db::Path &qr2_obj = *b.shape_repository ().repository (db::Path::tag ()).begin ();
|
||||||
EXPECT_EQ (& qr2.obj () == &qr2_obj, true);
|
EXPECT_EQ (& qr2.obj () == &qr2_obj, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -901,103 +901,98 @@ class DBLayout_TestClass < TestBase
|
||||||
assert_equal(dump_layer(lll, 0, "c0"), "(0,100;1000,1200); (0,100;1000,1200); (1200,0;2200,1100); (1200,0;2200,1100); (-1200,0;-100,1000); (-1200,0;-100,1000)")
|
assert_equal(dump_layer(lll, 0, "c0"), "(0,100;1000,1200); (0,100;1000,1200); (1200,0;2200,1100); (1200,0;2200,1100); (-1200,0;-100,1000); (-1200,0;-100,1000)")
|
||||||
assert_equal(dump_layer(lll, 1, "c0"), "(0,100;1000,1200); (100,0;1100,1100)")
|
assert_equal(dump_layer(lll, 1, "c0"), "(0,100;1000,1200); (100,0;1100,1100)")
|
||||||
|
|
||||||
# TODO: undo tests crashes in non-editable mode! Should be checked properly.
|
assert_equal(m.has_undo?, true)
|
||||||
if lll.is_editable?
|
assert_equal(m.has_redo?, false)
|
||||||
|
assert_equal(m.transaction_for_undo, "9")
|
||||||
|
|
||||||
assert_equal(m.has_undo?, true)
|
m.undo
|
||||||
assert_equal(m.has_redo?, false)
|
assert_equal(m.has_undo?, true)
|
||||||
assert_equal(m.transaction_for_undo, "9")
|
assert_equal(m.has_redo?, true)
|
||||||
|
assert_equal(m.transaction_for_undo, "8")
|
||||||
|
|
||||||
m.undo
|
assert_equal(dump_layer(l, 0, "c0"), "(0,100;1000,1200); (0,100;1000,1200); (1200,0;2200,1100); (1200,0;2200,1100); (-1200,0;-100,1000); (-1200,0;-100,1000)")
|
||||||
assert_equal(m.has_undo?, true)
|
assert_equal(dump_layer(l, 1, "c0"), "(0,100;1000,1200); (100,0;1100,1100)")
|
||||||
assert_equal(m.has_redo?, true)
|
|
||||||
assert_equal(m.transaction_for_undo, "8")
|
|
||||||
|
|
||||||
assert_equal(dump_layer(l, 0, "c0"), "(0,100;1000,1200); (0,100;1000,1200); (1200,0;2200,1100); (1200,0;2200,1100); (-1200,0;-100,1000); (-1200,0;-100,1000)")
|
m.undo
|
||||||
assert_equal(dump_layer(l, 1, "c0"), "(0,100;1000,1200); (100,0;1100,1100)")
|
assert_equal(m.has_undo?, true)
|
||||||
|
assert_equal(m.has_redo?, true)
|
||||||
|
assert_equal(m.transaction_for_undo, "7")
|
||||||
|
|
||||||
m.undo
|
assert_equal(dump_layer(l, 0, "c0"), "(0,100;1000,1200); (0,100;1000,1200); (1200,0;2200,1100); (-1200,0;-100,1000)")
|
||||||
assert_equal(m.has_undo?, true)
|
assert_equal(dump_layer(l, 1, "c0"), "(0,100;1000,1200); (100,0;1100,1100)")
|
||||||
assert_equal(m.has_redo?, true)
|
|
||||||
assert_equal(m.transaction_for_undo, "7")
|
|
||||||
|
|
||||||
assert_equal(dump_layer(l, 0, "c0"), "(0,100;1000,1200); (0,100;1000,1200); (1200,0;2200,1100); (-1200,0;-100,1000)")
|
m.undo
|
||||||
assert_equal(dump_layer(l, 1, "c0"), "(0,100;1000,1200); (100,0;1100,1100)")
|
assert_equal(m.has_undo?, true)
|
||||||
|
assert_equal(m.has_redo?, true)
|
||||||
|
assert_equal(m.transaction_for_undo, "6")
|
||||||
|
|
||||||
m.undo
|
assert_equal(dump_layer(l, 0, "c0"), "(0,100;1000,1200); (1200,0;2200,1100); (-1200,0;-100,1000)")
|
||||||
assert_equal(m.has_undo?, true)
|
assert_equal(dump_layer(l, 1, "c0"), "(0,100;1000,1200); (0,100;1000,1200); (100,0;1100,1100)")
|
||||||
assert_equal(m.has_redo?, true)
|
|
||||||
assert_equal(m.transaction_for_undo, "6")
|
|
||||||
|
|
||||||
assert_equal(dump_layer(l, 0, "c0"), "(0,100;1000,1200); (1200,0;2200,1100); (-1200,0;-100,1000)")
|
m.undo
|
||||||
assert_equal(dump_layer(l, 1, "c0"), "(0,100;1000,1200); (0,100;1000,1200); (100,0;1100,1100)")
|
assert_equal(m.has_undo?, true)
|
||||||
|
assert_equal(m.has_redo?, true)
|
||||||
|
assert_equal(m.transaction_for_undo, "5")
|
||||||
|
|
||||||
m.undo
|
assert_equal(dump_layer(l, 0, "c0"), "(1200,0;2200,1100); (-1200,0;-100,1000)")
|
||||||
assert_equal(m.has_undo?, true)
|
assert_equal(dump_layer(l, 1, "c0"), "(0,100;1000,1200); (0,100;1000,1200); (100,0;1100,1100)")
|
||||||
assert_equal(m.has_redo?, true)
|
|
||||||
assert_equal(m.transaction_for_undo, "5")
|
|
||||||
|
|
||||||
assert_equal(dump_layer(l, 0, "c0"), "(1200,0;2200,1100); (-1200,0;-100,1000)")
|
m.undo
|
||||||
assert_equal(dump_layer(l, 1, "c0"), "(0,100;1000,1200); (0,100;1000,1200); (100,0;1100,1100)")
|
assert_equal(m.has_undo?, true)
|
||||||
|
assert_equal(m.has_redo?, true)
|
||||||
|
assert_equal(m.transaction_for_undo, "4")
|
||||||
|
|
||||||
m.undo
|
assert_equal(dump_layer(l, 0, "c0"), "")
|
||||||
assert_equal(m.has_undo?, true)
|
assert_equal(dump_layer(l, 1, "c0"), "(0,100;1000,1200); (0,100;1000,1200); (100,0;1100,1100); (1200,0;2200,1100); (-1200,0;-100,1000)")
|
||||||
assert_equal(m.has_redo?, true)
|
|
||||||
assert_equal(m.transaction_for_undo, "4")
|
|
||||||
|
|
||||||
assert_equal(dump_layer(l, 0, "c0"), "")
|
m.undo
|
||||||
assert_equal(dump_layer(l, 1, "c0"), "(0,100;1000,1200); (0,100;1000,1200); (100,0;1100,1100); (1200,0;2200,1100); (-1200,0;-100,1000)")
|
assert_equal(m.has_undo?, true)
|
||||||
|
assert_equal(m.has_redo?, true)
|
||||||
|
assert_equal(m.transaction_for_undo, "3")
|
||||||
|
|
||||||
m.undo
|
assert_equal(dump_layer(l, 1, "c0"), "")
|
||||||
assert_equal(m.has_undo?, true)
|
assert_equal(dump_layer(l, 0, "c0"), "(0,100;1000,1200); (0,100;1000,1200); (100,0;1100,1100); (1200,0;2200,1100); (-1200,0;-100,1000)")
|
||||||
assert_equal(m.has_redo?, true)
|
|
||||||
assert_equal(m.transaction_for_undo, "3")
|
|
||||||
|
|
||||||
assert_equal(dump_layer(l, 1, "c0"), "")
|
m.undo
|
||||||
assert_equal(dump_layer(l, 0, "c0"), "(0,100;1000,1200); (0,100;1000,1200); (100,0;1100,1100); (1200,0;2200,1100); (-1200,0;-100,1000)")
|
assert_equal(m.has_undo?, true)
|
||||||
|
assert_equal(m.has_redo?, true)
|
||||||
|
assert_equal(m.transaction_for_undo, "2")
|
||||||
|
|
||||||
m.undo
|
assert_equal(dump_layer(l, 1, "c0"), "(0,100;1000,1200); (0,100;1000,1200); (100,0;1100,1100); (1200,0;2200,1100); (-1200,0;-100,1000)")
|
||||||
assert_equal(m.has_undo?, true)
|
assert_equal(dump_layer(l, 0, "c0"), "(0,100;1000,1200); (0,100;1000,1200); (100,0;1100,1100); (1200,0;2200,1100); (-1200,0;-100,1000)")
|
||||||
assert_equal(m.has_redo?, true)
|
|
||||||
assert_equal(m.transaction_for_undo, "2")
|
|
||||||
|
|
||||||
assert_equal(dump_layer(l, 1, "c0"), "(0,100;1000,1200); (0,100;1000,1200); (100,0;1100,1100); (1200,0;2200,1100); (-1200,0;-100,1000)")
|
m.undo
|
||||||
assert_equal(dump_layer(l, 0, "c0"), "(0,100;1000,1200); (0,100;1000,1200); (100,0;1100,1100); (1200,0;2200,1100); (-1200,0;-100,1000)")
|
assert_equal(m.has_undo?, true)
|
||||||
|
assert_equal(m.has_redo?, true)
|
||||||
|
assert_equal(m.transaction_for_undo, "1")
|
||||||
|
|
||||||
m.undo
|
assert_equal(dump_layer(l, 0, "c0"), "")
|
||||||
assert_equal(m.has_undo?, true)
|
assert_equal(dump_layer(l, 1, "c0"), "(0,100;1000,1200); (0,100;1000,1200); (100,0;1100,1100); (1200,0;2200,1100); (-1200,0;-100,1000)")
|
||||||
assert_equal(m.has_redo?, true)
|
|
||||||
assert_equal(m.transaction_for_undo, "1")
|
|
||||||
|
|
||||||
assert_equal(dump_layer(l, 0, "c0"), "")
|
m.undo
|
||||||
assert_equal(dump_layer(l, 1, "c0"), "(0,100;1000,1200); (0,100;1000,1200); (100,0;1100,1100); (1200,0;2200,1100); (-1200,0;-100,1000)")
|
assert_equal(m.has_undo?, false)
|
||||||
|
assert_equal(m.has_redo?, true)
|
||||||
|
assert_equal(m.transaction_for_redo, "1")
|
||||||
|
|
||||||
m.undo
|
assert_equal(dump_layer(l, 0, "c0"), "(0,100;1000,1200); (0,100;1000,1200); (100,0;1100,1100); (1200,0;2200,1100); (-1200,0;-100,1000)")
|
||||||
assert_equal(m.has_undo?, false)
|
assert_equal(dump_layer(l, 1, "c0"), "")
|
||||||
assert_equal(m.has_redo?, true)
|
|
||||||
assert_equal(m.transaction_for_redo, "1")
|
|
||||||
|
|
||||||
assert_equal(dump_layer(l, 0, "c0"), "(0,100;1000,1200); (0,100;1000,1200); (100,0;1100,1100); (1200,0;2200,1100); (-1200,0;-100,1000)")
|
m.redo
|
||||||
assert_equal(dump_layer(l, 1, "c0"), "")
|
assert_equal(m.has_undo?, true)
|
||||||
|
assert_equal(m.has_redo?, true)
|
||||||
|
assert_equal(m.transaction_for_redo, "2")
|
||||||
|
|
||||||
m.redo
|
assert_equal(dump_layer(l, 0, "c0"), "")
|
||||||
assert_equal(m.has_undo?, true)
|
assert_equal(dump_layer(l, 1, "c0"), "(0,100;1000,1200); (0,100;1000,1200); (100,0;1100,1100); (1200,0;2200,1100); (-1200,0;-100,1000)")
|
||||||
assert_equal(m.has_redo?, true)
|
|
||||||
assert_equal(m.transaction_for_redo, "2")
|
|
||||||
|
|
||||||
assert_equal(dump_layer(l, 0, "c0"), "")
|
assert_equal(dump_layer(ll, 0, "c0"), "(0,100;1000,1200); (0,100;1000,1200); (1200,0;2200,1100); (1200,0;2200,1100); (-1200,0;-100,1000); (-1200,0;-100,1000)")
|
||||||
assert_equal(dump_layer(l, 1, "c0"), "(0,100;1000,1200); (0,100;1000,1200); (100,0;1100,1100); (1200,0;2200,1100); (-1200,0;-100,1000)")
|
assert_equal(dump_layer(ll, 1, "c0"), "(0,100;1000,1200); (100,0;1100,1100)")
|
||||||
|
|
||||||
assert_equal(dump_layer(ll, 0, "c0"), "(0,100;1000,1200); (0,100;1000,1200); (1200,0;2200,1100); (1200,0;2200,1100); (-1200,0;-100,1000); (-1200,0;-100,1000)")
|
l.destroy
|
||||||
assert_equal(dump_layer(ll, 1, "c0"), "(0,100;1000,1200); (100,0;1100,1100)")
|
m.destroy
|
||||||
|
|
||||||
l.destroy
|
assert_equal(dump_layer(lll, 0, "c0"), "(0,100;1000,1200); (0,100;1000,1200); (1200,0;2200,1100); (1200,0;2200,1100); (-1200,0;-100,1000); (-1200,0;-100,1000)")
|
||||||
m.destroy
|
assert_equal(dump_layer(lll, 1, "c0"), "(0,100;1000,1200); (100,0;1100,1100)")
|
||||||
|
|
||||||
assert_equal(dump_layer(lll, 0, "c0"), "(0,100;1000,1200); (0,100;1000,1200); (1200,0;2200,1100); (1200,0;2200,1100); (-1200,0;-100,1000); (-1200,0;-100,1000)")
|
|
||||||
assert_equal(dump_layer(lll, 1, "c0"), "(0,100;1000,1200); (100,0;1100,1100)")
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue