From 1e09bee1b673c5cc17fd420cf8215499279c68f2 Mon Sep 17 00:00:00 2001
From: Matthias Koefferlein
Date: Sun, 19 Nov 2023 20:48:44 +0100
Subject: [PATCH 1/4] Fixed issue #1534 (Layout::dup does not copy properties)
---
src/db/db/dbLayout.cc | 2 ++
src/doc/doc/about/packages.xml | 2 +-
testdata/ruby/dbLayoutTests1.rb | 18 ++++++++++++++++++
3 files changed, 21 insertions(+), 1 deletion(-)
diff --git a/src/db/db/dbLayout.cc b/src/db/db/dbLayout.cc
index ab60ae7877..c3505b24b1 100644
--- a/src/db/db/dbLayout.cc
+++ b/src/db/db/dbLayout.cc
@@ -531,6 +531,8 @@ Layout::operator= (const Layout &d)
m_tech_name = d.m_tech_name;
+ m_prop_id = d.m_prop_id;
+
}
return *this;
}
diff --git a/src/doc/doc/about/packages.xml b/src/doc/doc/about/packages.xml
index ad3bfe0600..28dbc6689d 100644
--- a/src/doc/doc/about/packages.xml
+++ b/src/doc/doc/about/packages.xml
@@ -138,7 +138,7 @@
this can be a web server or a folder on
a file server. KLayout talks WebDAV, so the web server needs to offer WebDAV
access. A subversion (SVN) server provides WebDAV by default, so this is a good
- choice. For the packages themselves Git or WebDAV/Subversion can be used. You
+ choice. For the packages themselves, Git or WebDAV/Subversion can be used. You
need to specify the protocol in the package URL (see below).
diff --git a/testdata/ruby/dbLayoutTests1.rb b/testdata/ruby/dbLayoutTests1.rb
index 284e1fea40..a9d084beb2 100644
--- a/testdata/ruby/dbLayoutTests1.rb
+++ b/testdata/ruby/dbLayoutTests1.rb
@@ -2082,6 +2082,24 @@ def test_23
end
+ def test_24
+
+ ly = RBA::Layout::new
+ ly.set_property("k1", 17)
+ ly.set_property(17, "42")
+
+ assert_equal(17, ly.property("k1"))
+ assert_equal("42", ly.property(17))
+ assert_equal(nil, ly.property(42))
+
+ ly_dup = ly.dup
+
+ assert_equal(17, ly_dup.property("k1"))
+ assert_equal("42", ly_dup.property(17))
+ assert_equal(nil, ly_dup.property(42))
+
+ end
+
# Iterating while flatten
def test_issue200
From 6e589e2bb31e8ef0391f47217dcb495284e1dc00 Mon Sep 17 00:00:00 2001
From: Matthias Koefferlein
Date: Sun, 19 Nov 2023 21:14:32 +0100
Subject: [PATCH 2/4] Fixed issue #1533 (KLayout crashing with two consecutive
calls of the same LayoutView::show_layout command)
---
.../laybasic/gsiDeclLayLayoutViewBase.cc | 15 +++++++++++---
src/laybasic/laybasic/layCellView.cc | 15 ++++++++++++++
src/laybasic/laybasic/layCellView.h | 8 ++++++++
testdata/ruby/layLayoutView.rb | 20 +++++++++++++++++++
4 files changed, 55 insertions(+), 3 deletions(-)
diff --git a/src/laybasic/laybasic/gsiDeclLayLayoutViewBase.cc b/src/laybasic/laybasic/gsiDeclLayLayoutViewBase.cc
index 39dbe24042..5e9af3dd0c 100644
--- a/src/laybasic/laybasic/gsiDeclLayLayoutViewBase.cc
+++ b/src/laybasic/laybasic/gsiDeclLayLayoutViewBase.cc
@@ -277,7 +277,10 @@ static unsigned int show_layout1 (lay::LayoutViewBase *view, db::Layout *layout,
{
// the layout gets held by the LayoutHandle object
layout->keep ();
- lay::LayoutHandle *handle = new lay::LayoutHandle (layout, std::string ());
+ lay::LayoutHandle *handle = lay::LayoutHandle::find_layout (layout);
+ if (! handle) {
+ handle = new lay::LayoutHandle (layout, std::string ());
+ }
return view->add_layout (handle, add_cellview);
}
@@ -285,7 +288,10 @@ static unsigned int show_layout2 (lay::LayoutViewBase *view, db::Layout *layout,
{
// the layout gets held by the LayoutHandle object
layout->keep ();
- lay::LayoutHandle *handle = new lay::LayoutHandle (layout, std::string ());
+ lay::LayoutHandle *handle = lay::LayoutHandle::find_layout (layout);
+ if (! handle) {
+ handle = new lay::LayoutHandle (layout, std::string ());
+ }
handle->set_tech_name (tech);
return view->add_layout (handle, add_cellview);
}
@@ -294,7 +300,10 @@ static unsigned int show_layout3 (lay::LayoutViewBase *view, db::Layout *layout,
{
// the layout gets held by the LayoutHandle object
layout->keep ();
- lay::LayoutHandle *handle = new lay::LayoutHandle (layout, std::string ());
+ lay::LayoutHandle *handle = lay::LayoutHandle::find_layout (layout);
+ if (! handle) {
+ handle = new lay::LayoutHandle (layout, std::string ());
+ }
handle->set_tech_name (tech);
return view->add_layout (handle, add_cellview, initialize_layers);
}
diff --git a/src/laybasic/laybasic/layCellView.cc b/src/laybasic/laybasic/layCellView.cc
index d0afaa1035..55c97743f0 100644
--- a/src/laybasic/laybasic/layCellView.cc
+++ b/src/laybasic/laybasic/layCellView.cc
@@ -272,6 +272,17 @@ LayoutHandle::find (const std::string &name)
}
}
+LayoutHandle *
+LayoutHandle::find_layout (const db::Layout *layout)
+{
+ for (auto h = ms_dict.begin (); h != ms_dict.end (); ++h) {
+ if (h->second->mp_layout == layout) {
+ return h->second;
+ }
+ }
+ return 0;
+}
+
void
LayoutHandle::get_names (std::vector &names)
{
@@ -484,6 +495,10 @@ LayoutHandleRef::operator= (const LayoutHandleRef &r)
void
LayoutHandleRef::set (LayoutHandle *h)
{
+ if (mp_handle == h) {
+ return;
+ }
+
if (mp_handle) {
mp_handle->remove_ref ();
mp_handle = 0;
diff --git a/src/laybasic/laybasic/layCellView.h b/src/laybasic/laybasic/layCellView.h
index 0f5bee9d96..7f350f6913 100644
--- a/src/laybasic/laybasic/layCellView.h
+++ b/src/laybasic/laybasic/layCellView.h
@@ -144,6 +144,14 @@ class LAYBASIC_PUBLIC LayoutHandle
*/
static LayoutHandle *find (const std::string &name);
+ /**
+ * @brief Finds a handle by layout object
+ *
+ * @param layout The Layout object bound to the handle
+ * @return 0, if there is no layout object with this name. Otherwise a pointer to its handle
+ */
+ static LayoutHandle *find_layout (const db::Layout *layout);
+
/**
* @brief Gets the names of all registered layout objects
*/
diff --git a/testdata/ruby/layLayoutView.rb b/testdata/ruby/layLayoutView.rb
index fdd384cc6a..d2c29ea0bd 100644
--- a/testdata/ruby/layLayoutView.rb
+++ b/testdata/ruby/layLayoutView.rb
@@ -550,6 +550,26 @@ def test_7
end
+ # issue-1533
+ def test_8
+
+ if !RBA.constants.member?(:Application)
+ return
+ end
+
+ app = RBA::Application.instance
+ mw = app.main_window
+ mw.close_all
+ mw.create_view
+
+ ly = RBA::Layout::new
+ mw.current_view.show_layout(ly, false)
+
+ # was crashing
+ mw.current_view.show_layout(ly, false)
+
+ end
+
end
load("test_epilogue.rb")
From 8b805d8815b1988ba2227e52e3440d71bf49e89d Mon Sep 17 00:00:00 2001
From: Matthias Koefferlein
Date: Sun, 19 Nov 2023 21:24:10 +0100
Subject: [PATCH 3/4] Implemented fix for issue #1527 (Marker Database Browser:
add context menu to Info widget)
---
src/layui/layui/rdbMarkerBrowserPage.cc | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/src/layui/layui/rdbMarkerBrowserPage.cc b/src/layui/layui/rdbMarkerBrowserPage.cc
index e9cab1a57a..0b795ccab2 100644
--- a/src/layui/layui/rdbMarkerBrowserPage.cc
+++ b/src/layui/layui/rdbMarkerBrowserPage.cc
@@ -1506,6 +1506,18 @@ MarkerBrowserPage::MarkerBrowserPage (QWidget * /*parent*/)
markers_list->header ()->setSortIndicatorShown (true);
markers_list->header ()->setMinimumSectionSize (24);
+ QAction *select_all_info_action = new QAction (this);
+ select_all_info_action->setText (tr ("Select All"));
+ connect (select_all_info_action, SIGNAL (triggered ()), info_text, SLOT (selectAll ()));
+
+ QAction *copy_info_action = new QAction (this);
+ copy_info_action->setText (tr ("Copy"));
+ connect (copy_info_action, SIGNAL (triggered ()), info_text, SLOT (copy ()));
+
+ info_text->addAction (select_all_info_action);
+ info_text->addAction (copy_info_action);
+ info_text->setContextMenuPolicy (Qt::ActionsContextMenu);
+
list_shapes_cb->setChecked (m_list_shapes);
connect (markers_list, SIGNAL (doubleClicked (const QModelIndex &)), this, SLOT (marker_double_clicked (const QModelIndex &)));
From 9565a55a3be57a940d6b57491c7f5a75623473ad Mon Sep 17 00:00:00 2001
From: Matthias Koefferlein
Date: Sun, 19 Nov 2023 21:52:29 +0100
Subject: [PATCH 4/4] Fixed issue #1522 (Changing ruler/annotation from script
weirdly interferes with pya.Application.commit_config)
---
src/ant/ant/antPlugin.cc | 77 +++++++++++++++++++---------------------
1 file changed, 37 insertions(+), 40 deletions(-)
diff --git a/src/ant/ant/antPlugin.cc b/src/ant/ant/antPlugin.cc
index 037ebfc3ed..c5c6b5ad12 100644
--- a/src/ant/ant/antPlugin.cc
+++ b/src/ant/ant/antPlugin.cc
@@ -45,24 +45,6 @@ namespace ant
static PluginDeclaration *sp_instance = 0;
-PluginDeclaration::PluginDeclaration ()
- : m_current_template (0),
- m_current_template_updated (true), m_templates_updated (true)
-{
- sp_instance = this;
-}
-
-PluginDeclaration::~PluginDeclaration ()
-{
- sp_instance = 0;
-}
-
-PluginDeclaration *
-PluginDeclaration::instance ()
-{
- return sp_instance;
-}
-
static std::vector make_standard_templates ()
{
std::vector templates;
@@ -92,6 +74,24 @@ static std::vector make_standard_templates ()
return templates;
}
+PluginDeclaration::PluginDeclaration ()
+ : m_current_template (0),
+ m_current_template_updated (true), m_templates_updated (true)
+{
+ sp_instance = this;
+}
+
+PluginDeclaration::~PluginDeclaration ()
+{
+ sp_instance = 0;
+}
+
+PluginDeclaration *
+PluginDeclaration::instance ()
+{
+ return sp_instance;
+}
+
void
PluginDeclaration::get_options (std::vector < std::pair > &options) const
{
@@ -281,25 +281,24 @@ PluginDeclaration::update_current_template ()
return;
}
- if (m_current_template >= 0 && m_current_template < int (m_templates.size ())) {
-
- std::vector menu_entries = mp->menu ()->group ("ruler_mode_group");
- for (std::vector::const_iterator m = menu_entries.begin (); m != menu_entries.end (); ++m) {
- lay::Action *action = mp->menu ()->action (*m);
+ std::vector menu_entries = mp->menu ()->group ("ruler_mode_group");
+ for (std::vector::const_iterator m = menu_entries.begin (); m != menu_entries.end (); ++m) {
+ lay::Action *action = mp->menu ()->action (*m);
+ if (m_current_template >= 0 && m_current_template < int (m_templates.size ())) {
action->set_title (m_templates [m_current_template].title ());
+ } else {
+ action->set_title (std::string ());
}
-
- if (m_templates.size () > 1) {
+ }
- tl::weak_collection::iterator it = m_actions.begin ();
- int index = 0;
- for (std::vector::const_iterator tt = m_templates.begin (); tt != m_templates.end () && it != m_actions.end (); ++tt, ++it, ++index) {
- if (it.operator -> ()) {
- it->set_checked (index == m_current_template);
- }
+ if (m_templates.size () > 1) {
+ tl::weak_collection::iterator it = m_actions.begin ();
+ int index = 0;
+ for (std::vector::const_iterator tt = m_templates.begin (); tt != m_templates.end () && it != m_actions.end (); ++tt, ++it, ++index) {
+ if (it.operator -> ()) {
+ it->set_checked (index == m_current_template);
}
}
-
}
m_current_template_updated = false;
@@ -313,15 +312,13 @@ PluginDeclaration::update_menu ()
return;
}
- if (m_current_template < 0 || m_current_template >= int (m_templates.size ())) {
- m_current_template = 0;
- }
-
- if (m_current_template >= 0 && m_current_template < int (m_templates.size ())) {
- std::vector menu_entries = mp->menu ()->group ("ruler_mode_group");
- for (std::vector::const_iterator m = menu_entries.begin (); m != menu_entries.end (); ++m) {
- lay::Action *action = mp->menu ()->action (*m);
+ std::vector menu_entries = mp->menu ()->group ("ruler_mode_group");
+ for (std::vector::const_iterator m = menu_entries.begin (); m != menu_entries.end (); ++m) {
+ lay::Action *action = mp->menu ()->action (*m);
+ if (m_current_template >= 0 && m_current_template < int (m_templates.size ())) {
action->set_title (m_templates [m_current_template].title ());
+ } else {
+ action->set_title (std::string ());
}
}