From 9125ed703533204fbd70170a3236a818184e320e Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sat, 23 Mar 2024 19:23:21 +0100 Subject: [PATCH 1/3] [consider merging] fixed a linker problem for debug builds --- src/tl/tl/tlOptional.cc | 2 +- src/tl/tl/tlOptional.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tl/tl/tlOptional.cc b/src/tl/tl/tlOptional.cc index ba2774439f..d7ee370b23 100644 --- a/src/tl/tl/tlOptional.cc +++ b/src/tl/tl/tlOptional.cc @@ -25,6 +25,6 @@ namespace tl { -extern const nullopt_t nullopt = nullopt_t (); +const nullopt_t nullopt = nullopt_t (); } // namespace tl diff --git a/src/tl/tl/tlOptional.h b/src/tl/tl/tlOptional.h index c30fa66791..3893d6ac03 100644 --- a/src/tl/tl/tlOptional.h +++ b/src/tl/tl/tlOptional.h @@ -34,7 +34,7 @@ namespace tl struct nullopt_t {}; -extern const nullopt_t nullopt; +extern TL_PUBLIC const nullopt_t nullopt; /** * @brief Poor man's partial implementation of C++17's std::optional From 3b0a34b9559e7eea4042543df90fda3d1b9130dd Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sun, 24 Mar 2024 12:31:44 +0100 Subject: [PATCH 2/3] [consider merging] Avoid a segfault when changing the default grids. --- src/lay/lay/layMainConfigPages.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lay/lay/layMainConfigPages.cc b/src/lay/lay/layMainConfigPages.cc index a7634e4e56..95e724196b 100644 --- a/src/lay/lay/layMainConfigPages.cc +++ b/src/lay/lay/layMainConfigPages.cc @@ -525,7 +525,7 @@ CustomizeMenuConfigPage::commit (lay::Dispatcher *dispatcher) std::map::iterator cb = m_current_bindings.find (kb->first); if (cb != m_current_bindings.end ()) { lay::Action *a = dispatcher->menu ()->action (kb->first); - if (cb->second != a->get_default_shortcut ()) { + if (a && cb->second != a->get_default_shortcut ()) { if (cb->second.empty ()) { kb->second = lay::Action::no_shortcut (); } else { From 376058f34bb0852d0aea6f259116d8bb083734ec Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sun, 24 Mar 2024 12:48:53 +0100 Subject: [PATCH 3/3] Implemented fix for issue-1662 (Strong default grids) --- src/db/db/dbTechnology.cc | 28 ++++++++-- src/db/db/dbTechnology.h | 9 ++++ src/db/db/gsiDeclDbTechnologies.cc | 31 ++++++++++- src/lay/lay/MainConfigPage3.ui | 82 ++++++++++++++++-------------- src/lay/lay/TechBaseEditorPage.ui | 10 +++- src/lay/lay/layMainWindow.cc | 44 ++++++++++++++-- src/lay/lay/layMainWindow.h | 3 ++ testdata/ruby/dbTechnologies.rb | 19 +++++++ 8 files changed, 178 insertions(+), 48 deletions(-) diff --git a/src/db/db/dbTechnology.cc b/src/db/db/dbTechnology.cc index 2910fbbabd..84bd4118e9 100644 --- a/src/db/db/dbTechnology.cc +++ b/src/db/db/dbTechnology.cc @@ -347,12 +347,10 @@ Technology::get_display_string () const return d; } -std::vector -Technology::default_grid_list () const +static void +parse_default_grids (const std::string &s, std::vector &grids, double &default_grid) { - tl::Extractor ex (m_default_grids.c_str ()); - - std::vector grids; + tl::Extractor ex (s.c_str ()); // convert the list of grids to a list of doubles while (! ex.at_end ()) { @@ -361,12 +359,32 @@ Technology::default_grid_list () const break; } grids.push_back (g); + if (ex.test ("!")) { + default_grid = g; + } ex.test (","); } +} +std::vector +Technology::default_grid_list () const +{ + std::vector grids; + double default_grid = 0.0; + parse_default_grids (m_default_grids, grids, default_grid); return grids; } +double +Technology::default_grid () const +{ + std::vector grids; + double default_grid = 0.0; + parse_default_grids (m_default_grids, grids, default_grid); + return default_grid; +} + + tl::XMLElementList Technology::xml_elements () { diff --git a/src/db/db/dbTechnology.h b/src/db/db/dbTechnology.h index e06ddca14d..2fa1c6f5e6 100644 --- a/src/db/db/dbTechnology.h +++ b/src/db/db/dbTechnology.h @@ -480,6 +480,15 @@ class DB_PUBLIC Technology */ std::vector default_grid_list () const; + /** + * @brief Gets the default grid (strong grid), parsed from the list + * + * The default grid is the one marked with an exclamation mark in the + * grid list (e.g. "0.01!,0.02,0.05"). If there is not such default + * grid, this method returns zero. + */ + double default_grid () const; + /** * @brief Sets the default default grids */ diff --git a/src/db/db/gsiDeclDbTechnologies.cc b/src/db/db/gsiDeclDbTechnologies.cc index de670fa4f7..bc3d6f9d00 100644 --- a/src/db/db/gsiDeclDbTechnologies.cc +++ b/src/db/db/gsiDeclDbTechnologies.cc @@ -136,7 +136,7 @@ gsi::Class technology_component_decl ("db", "Technology DB_PUBLIC gsi::Class &decl_dbTechnologyComponent () { return technology_component_decl; } static void -set_default_grid_list (db::Technology *tech, const std::vector &grids) +set_default_grid_list2 (db::Technology *tech, const std::vector &grids, double default_grid) { std::string r; for (auto g = grids.begin (); g != grids.end (); ++g) { @@ -144,10 +144,19 @@ set_default_grid_list (db::Technology *tech, const std::vector &grids) r += ","; } r += tl::micron_to_string (*g); + if (db::coord_traits::equals (*g, default_grid)) { + r += "!"; + } } tech->set_default_grids (r); } +static void +set_default_grid_list (db::Technology *tech, const std::vector &grids) +{ + set_default_grid_list2 (tech, grids, 0.0); +} + gsi::Class technology_decl ("db", "Technology", gsi::method ("name", &db::Technology::name, "@brief Gets the name of the technology" @@ -238,12 +247,32 @@ gsi::Class technology_decl ("db", "Technology", "\n" "This property has been introduced in version 0.28.17." ) + + gsi::method ("default_grid", &db::Technology::default_grid, + "@brief Gets the default grid\n" + "\n" + "The default grid is a specific one from the default grid list.\n" + "It indicates the one that is taken if the current grid is not matching one of " + "the default grids.\n" + "\n" + "To set the default grid, use \\set_default_grids.\n" + "\n" + "This property has been introduced in version 0.29." + ) + gsi::method_ext ("default_grids=", &set_default_grid_list, gsi::arg ("grids"), "@brief Sets the default grids\n" "If not empty, this list replaces the global grid list for this technology.\n" + "Note that this method will reset the default grid (see \\default_grid). Use " + "\\set_default_grids to set the default grids and the strong default one.\n" "\n" "This property has been introduced in version 0.28.17." ) + + gsi::method_ext ("set_default_grids", &set_default_grid_list2, gsi::arg ("grids"), gsi::arg ("default_grid", 0.0), + "@brief Sets the default grids and the strong default one\n" + "See \\default_grids and \\default_grid for a description of this property.\n" + "Note that the default grid has to be a member of the 'grids' array to become active.\n" + "\n" + "This method has been introduced in version 0.29." + ) + gsi::method ("layer_properties_file", &db::Technology::layer_properties_file, "@brief Gets the path of the layer properties file\n" "\n" diff --git a/src/lay/lay/MainConfigPage3.ui b/src/lay/lay/MainConfigPage3.ui index 54420b2737..614606a585 100644 --- a/src/lay/lay/MainConfigPage3.ui +++ b/src/lay/lay/MainConfigPage3.ui @@ -1,67 +1,75 @@ - + + MainConfigPage3 - - + + 0 0 - 475 - 81 + 504 + 180 - + Settings - - - 9 - - + + 6 + + 9 + - - + + Default Grids - - + + 9 - + 6 - - - + + + + + 0 + 0 + + + + Grids for "View" menu + + + + + + µm (g1,g2,...) - - - - - 7 - 0 + + + + 0 0 - - - - - 5 - 5 - 0 - 0 - + + + + <html>You can declare one grid a strong default to enforce an editing grid from this list. To do so, add an exclamation mark - e.g. "0.01!,0.02,0.05". +<br/><b>Note</b>: the general default grids can be overridden by technology specific default grids.</html> - - Grids for "View" menu + + true @@ -70,7 +78,7 @@ - + diff --git a/src/lay/lay/TechBaseEditorPage.ui b/src/lay/lay/TechBaseEditorPage.ui index 668e04ffee..17d89749d1 100644 --- a/src/lay/lay/TechBaseEditorPage.ui +++ b/src/lay/lay/TechBaseEditorPage.ui @@ -7,7 +7,7 @@ 0 0 625 - 587 + 616 @@ -331,6 +331,9 @@ properties The default database unit is used as database unit for freshly created layouts + + true + @@ -352,7 +355,10 @@ properties - These grids are available for selection from the "View" menu + These grids are available for selection from the "View" menu and will override the general ones. You can declare one grid as a strong default to enforce an editing grid from this list. To do so, add an exclamation mark to the grid - e.g. "0.01!,0.02,0.05". + + + true diff --git a/src/lay/lay/layMainWindow.cc b/src/lay/lay/layMainWindow.cc index 0eb2eb397c..b5083ae8b4 100644 --- a/src/lay/lay/layMainWindow.cc +++ b/src/lay/lay/layMainWindow.cc @@ -175,9 +175,11 @@ MainWindow::MainWindow (QApplication *app, const char *name, bool undo_enabled) m_disable_tab_selected (false), m_exited (false), dm_do_update_menu (this, &MainWindow::do_update_menu), + dm_do_update_grids (this, &MainWindow::do_update_grids), dm_do_update_mru_menus (this, &MainWindow::do_update_mru_menus), dm_exit (this, &MainWindow::exit), m_grid_micron (0.001), + m_default_grid (0.0), m_default_grids_updated (true), m_new_layout_current_panel (false), m_synchronized_views (false), @@ -583,7 +585,7 @@ MainWindow::technology_changed () } m_default_grids_updated = true; // potentially ... - dm_do_update_menu (); + dm_do_update_grids (); } void @@ -939,7 +941,7 @@ MainWindow::config_finalize () // Update the default grids menu if necessary if (m_default_grids_updated) { - dm_do_update_menu (); + dm_do_update_grids (); } // make the changes visible in the setup form if the form is visible @@ -972,6 +974,7 @@ MainWindow::configure (const std::string &name, const std::string &value) tl::Extractor ex (value.c_str ()); m_default_grids.clear (); + m_default_grid = 0.0; m_default_grids_updated = true; // convert the list of grids to a list of doubles @@ -980,6 +983,9 @@ MainWindow::configure (const std::string &name, const std::string &value) if (! ex.try_read (g)) { break; } + if (ex.test ("!")) { + m_default_grid = g; + } m_default_grids.push_back (g); ex.test (","); } @@ -4041,6 +4047,38 @@ MainWindow::menu_changed () dm_do_update_menu (); } +void +MainWindow::do_update_grids () +{ + const std::vector *grids = &m_default_grids; + double default_grid = m_default_grid; + + std::vector tech_grids; + lay::TechnologyController *tc = lay::TechnologyController::instance (); + if (tc && tc->active_technology ()) { + tech_grids = tc->active_technology ()->default_grid_list (); + if (! tech_grids.empty ()) { + grids = &tech_grids; + default_grid = tc->active_technology ()->default_grid (); + } + } + + if (default_grid > db::epsilon) { + for (auto g = grids->begin (); g != grids->end (); ++g) { + if (db::coord_traits::equals (*g, m_grid_micron)) { + default_grid = 0.0; + break; + } + } + } + + if (default_grid > db::epsilon) { + dispatcher ()->config_set (cfg_grid, default_grid); + } + + do_update_menu (); +} + void MainWindow::do_update_menu () { @@ -4082,7 +4120,7 @@ MainWindow::do_update_menu () lay::Action *ga = new lay::ConfigureAction (gs, cfg_grid, tl::to_string (*g)); ga->set_checkable (true); - ga->set_checked (fabs (*g - m_grid_micron) < 1e-10); + ga->set_checked (db::coord_traits::equals (*g, m_grid_micron)); for (std::vector::const_iterator t = group.begin (); t != group.end (); ++t) { menu ()->insert_item (*t + ".end", name, ga); diff --git a/src/lay/lay/layMainWindow.h b/src/lay/lay/layMainWindow.h index 326bc3c07d..64e457c89e 100644 --- a/src/lay/lay/layMainWindow.h +++ b/src/lay/lay/layMainWindow.h @@ -706,6 +706,7 @@ protected slots: protected: void update_content (); void do_update_menu (); + void do_update_grids (); void do_update_mru_menus (); bool eventFilter (QObject *watched, QEvent *event); @@ -753,6 +754,7 @@ protected slots: bool m_disable_tab_selected; bool m_exited; tl::DeferredMethod dm_do_update_menu; + tl::DeferredMethod dm_do_update_grids; tl::DeferredMethod dm_do_update_mru_menus; tl::DeferredMethod dm_exit; QTimer m_message_timer; @@ -765,6 +767,7 @@ protected slots: std::string m_initial_technology; double m_grid_micron; std::vector m_default_grids; + double m_default_grid; bool m_default_grids_updated; std::vector > m_key_bindings; bool m_new_layout_current_panel; diff --git a/testdata/ruby/dbTechnologies.rb b/testdata/ruby/dbTechnologies.rb index d1dc9cf933..3305eae6a8 100644 --- a/testdata/ruby/dbTechnologies.rb +++ b/testdata/ruby/dbTechnologies.rb @@ -105,10 +105,29 @@ def test_2 tech.default_grids = [] assert_equal(tech.default_grids.collect { |g| "%.12g" % g }.join(","), "") + assert_equal("%.12g" % tech.default_grid, "0") tech.default_grids = [0.001, 0.01, 0.2] assert_equal(tech.default_grids.collect { |g| "%.12g" % g }.join(","), "0.001,0.01,0.2") tech.default_grids = [1] assert_equal(tech.default_grids.collect { |g| "%.12g" % g }.join(","), "1") + assert_equal("%.12g" % tech.default_grid, "0") + + # setting the default grid + tech.set_default_grids([0.01,0.02,0.05], 0.02) + assert_equal(tech.default_grids.collect { |g| "%.12g" % g }.join(","), "0.01,0.02,0.05") + assert_equal("%.12g" % tech.default_grid, "0.02") + + # default grid must be a member of the default grid list + tech.set_default_grids([0.01,0.02,0.05], 0.2) + assert_equal(tech.default_grids.collect { |g| "%.12g" % g }.join(","), "0.01,0.02,0.05") + assert_equal("%.12g" % tech.default_grid, "0") + + # "default_grids=" resets the default grid + tech.set_default_grids([0.01,0.02,0.05], 0.02) + assert_equal("%.12g" % tech.default_grid, "0.02") + tech.default_grids = [1] + assert_equal(tech.default_grids.collect { |g| "%.12g" % g }.join(","), "1") + assert_equal("%.12g" % tech.default_grid, "0") tech.default_base_path = "/default/path" assert_equal(tech.default_base_path, "/default/path")