Repository: KLayout/klayout (language: python)

Issue:
A bug about layer undo
1. create a layer
2. create a box on the layer
3. delete the layer
4. press undo
5. create new layer
After those steps , I found the box is changing into the new layer
I thought there is something wrong of dbLayoutLayers.cc:263(LayoutLayers::do_insert_layer).
Maybe m_free_indices should find the index and remove it.


Discussion / hints:
You're right. Perfectly reproducible. 

I will debug the issue. Thanks for reporting it.

Matthias

Fix patch:
diff --git a/src/db/db/dbLayoutLayers.cc b/src/db/db/dbLayoutLayers.cc
index c4c5eef1e..d321da913 100644
--- a/src/db/db/dbLayoutLayers.cc
+++ b/src/db/db/dbLayoutLayers.cc
@@ -251,7 +251,7 @@ LayoutLayers::do_insert_layer (unsigned int index, bool special)
   if (index >= layers ()) {
 
     //  add layer to the end of the list.
-    //  add as may freelist entries as required.
+    //  add as many freelist entries as required.
     while (index > layers ()) {
       m_free_indices.push_back (layers ());
       m_layer_states.push_back (Free);
@@ -262,6 +262,14 @@ LayoutLayers::do_insert_layer (unsigned int index, bool special)
 
     tl_assert (m_layer_states [index] == Free);
     m_layer_states [index] = special ? Special : Normal;
+
+    //  remove from the list of free indexes (issue #1860)
+    for (auto i = m_free_indices.begin (); i != m_free_indices.end (); ++i) {
+      if (*i == index) {
+        m_free_indices.erase (i);
+        break;
+      }
+    }
   
   }
 


Test patch:
diff --git a/src/db/unit_tests/dbLayoutTests.cc b/src/db/unit_tests/dbLayoutTests.cc
index d20db9187..6bd145478 100644
--- a/src/db/unit_tests/dbLayoutTests.cc
+++ b/src/db/unit_tests/dbLayoutTests.cc
@@ -871,3 +871,42 @@ TEST(11_FindPath)
   std::string d = tl::join (path.begin (), path.end (), ";");
   EXPECT_EQ (d, "cell_index=1 r90 *1 0,0;cell_index=2 r0 *1 100,200");
 }
+
+//  issue #1860
+TEST(100_UndoOfDeleteLayer)
+{
+  db::Manager m;
+  db::Layout l (&m);
+  db::Cell &top = l.cell (l.add_cell ("TOP"));
+
+  unsigned int li = 0, li2 = 0;
+
+  {
+    db::Transaction t (&m, "insert_layer");
+    li = l.insert_layer (db::LayerProperties (1, 0));
+  }
+
+  EXPECT_EQ (l.is_valid_layer (li), true);
+
+  {
+    db::Transaction t (&m, "remove_layer");
+    l.delete_layer (li);
+  }
+
+  EXPECT_EQ (l.is_valid_layer (li), false);
+
+  m.undo ();
+
+  EXPECT_EQ (l.is_valid_layer (li), true);
+  EXPECT_EQ (l.get_properties (li).to_string (), "1/0");
+
+  {
+    db::Transaction t (&m, "remove_layer");
+    li2 = l.insert_layer (db::LayerProperties (2, 0));
+  }
+
+  EXPECT_EQ (l.is_valid_layer (li2), true);
+  EXPECT_NE (li, li2);
+  EXPECT_EQ (l.get_properties (li).to_string (), "1/0");
+  EXPECT_EQ (l.get_properties (li2).to_string (), "2/0");
+}