Merge pull request #1943 from KLayout/hotfix-0.29.10

Hotfix 0.29.10
This commit is contained in:
Matthias Köfferlein 2024-12-03 19:02:04 +01:00 committed by GitHub
commit 9441024fd0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
15 changed files with 173 additions and 101 deletions

View File

@ -1,3 +1,13 @@
0.29.10 (2024-12-03):
* Bug: %GITHUB%/issues/1941 Crash with the navigator open
* Bug: %GITHUB%/issues/1942 Syntax error in pyi stubs
As a bonus, added defaults for Box#enlarge and Box#enlarged (dx, dy)
* Bugfix: Partial mode snapping now is object first, then grid
* Bugfix: Key bindings have not been properly read from the configuration file
The change in the configuration string structure triggered an old bug:
Toolbar buttons had a twofold configuration and only the last one was
considered. Changing the order of the entries could spoil the configuration.
0.29.9 (2024-12-01): 0.29.9 (2024-12-01):
* Bug: %GITHUB%/issues/1907 Locking layouts against modification during recursive iteration of instances and shapes * Bug: %GITHUB%/issues/1907 Locking layouts against modification during recursive iteration of instances and shapes
This prevents crashes in write-white-iterating scenarios This prevents crashes in write-white-iterating scenarios

View File

@ -1,3 +1,10 @@
klayout (0.29.10-1) unstable; urgency=low
* New features and bugfixes
- See changelog
-- Matthias Köfferlein <matthias@koefferlein.de> Mon, 02 Dec 2024 22:23:47 +0100
klayout (0.29.9-1) unstable; urgency=low klayout (0.29.9-1) unstable; urgency=low
* New features and bugfixes * New features and bugfixes

View File

@ -4,6 +4,7 @@
# clean up # clean up
rm -rf build dist rm -rf build dist
rm -rf python3-venv-make_stubs
python3 setup.py build python3 setup.py build
python3 setup.py bdist_wheel python3 setup.py bdist_wheel

View File

@ -388,7 +388,7 @@ struct box_defs
"\n" "\n"
"@return A reference to this box.\n" "@return A reference to this box.\n"
) + ) +
method_ext ("moved", &box_defs<C>::moved, gsi::arg ("dx, 0"), gsi::arg ("dy", 0), method_ext ("moved", &box_defs<C>::moved, gsi::arg ("dx", 0), gsi::arg ("dy", 0),
"@brief Moves the box by a certain distance\n" "@brief Moves the box by a certain distance\n"
"\n" "\n"
"This is a convenience method which takes two values instead of a Point object.\n" "This is a convenience method which takes two values instead of a Point object.\n"
@ -419,7 +419,7 @@ struct box_defs
"\n" "\n"
"@return The moved box.\n" "@return The moved box.\n"
) + ) +
method_ext ("enlarge", &box_defs<C>::enlarge, gsi::arg ("dx"), gsi::arg ("dy"), method_ext ("enlarge", &box_defs<C>::enlarge, gsi::arg ("dx", 0), gsi::arg ("dy", 0),
"@brief Enlarges the box by a certain amount.\n" "@brief Enlarges the box by a certain amount.\n"
"\n" "\n"
"\n" "\n"
@ -436,7 +436,7 @@ struct box_defs
"\n" "\n"
"@return A reference to this box.\n" "@return A reference to this box.\n"
) + ) +
method_ext ("enlarged", &box_defs<C>::enlarged, gsi::arg ("dx"), gsi::arg ("dy"), method_ext ("enlarged", &box_defs<C>::enlarged, gsi::arg ("dx", 0), gsi::arg ("dy", 0),
"@brief Enlarges the box by a certain amount.\n" "@brief Enlarges the box by a certain amount.\n"
"\n" "\n"
"\n" "\n"

View File

@ -1808,11 +1808,38 @@ PartialService::mouse_move_event (const db::DPoint &p, unsigned int buttons, boo
// for a single selected point or edge, m_start is the original position and we snap the target - // for a single selected point or edge, m_start is the original position and we snap the target -
// thus, we can bring the point on grid or to an object's edge or vertex // thus, we can bring the point on grid or to an object's edge or vertex
snap_details = snap2 (p); snap_details = snap2 (p);
if (snap_details.object_snap == lay::PointSnapToObjectResult::NoObject) { if (snap_details.object_snap == lay::PointSnapToObjectResult::NoObject) {
m_current = m_start + snap_move (p - m_start); m_current = m_start + snap_move (p - m_start);
} else { } else {
m_current = m_start + snap_move (snap_details.snapped_point - m_start);
auto snapped_to_object = snap_details.snapped_point;
m_current = snapped_to_object;
if (snap_details.object_snap != lay::PointSnapToObjectResult::ObjectVertex) {
// snap to grid on longer side of reference edge and to object on shorter
auto snapped_to_object_and_grid = m_start + snap_move (snapped_to_object - m_start);
if (std::abs (snap_details.object_ref.dx ()) > std::abs (snap_details.object_ref.dy ())) {
m_current.set_x (snapped_to_object_and_grid.x ());
// project to edge, so we always hit it
auto cp = snap_details.object_ref.cut_point (db::DEdge (m_current, m_current + db::DVector (0, 1.0)));
if (cp.first) {
m_current.set_y (cp.second.y ());
}
} else if (std::abs (snap_details.object_ref.dy ()) > std::abs (snap_details.object_ref.dx ())) {
m_current.set_y (snapped_to_object_and_grid.y ());
// project to edge, so we always hit it
auto cp = snap_details.object_ref.cut_point (db::DEdge (m_current, m_current + db::DVector (1.0, 0)));
if (cp.first) {
m_current.set_x (cp.second.x ());
}
}
}
mouse_cursor_from_snap_details (snap_details); mouse_cursor_from_snap_details (snap_details);
} }
} else { } else {

View File

@ -208,11 +208,6 @@ MacroController::uninitialize (lay::Dispatcher * /*root*/)
bool bool
MacroController::configure (const std::string &key, const std::string &value) MacroController::configure (const std::string &key, const std::string &value)
{ {
if (key == cfg_key_bindings) {
m_key_bindings = unpack_key_binding (value);
} else if (key == cfg_menu_items_hidden) {
m_menu_items_hidden = unpack_menu_items_hidden (value);
}
return false; return false;
} }
@ -810,21 +805,9 @@ MacroController::do_update_menu_with_macros ()
add_macro_items_to_menu (m_temp_macros, used_names, groups, tech); add_macro_items_to_menu (m_temp_macros, used_names, groups, tech);
add_macro_items_to_menu (lym::MacroCollection::root (), used_names, groups, tech); add_macro_items_to_menu (lym::MacroCollection::root (), used_names, groups, tech);
// apply the custom keyboard shortcuts // apply the custom keyboard shortcuts and hidden flags
for (std::vector<std::pair<std::string, std::string> >::const_iterator kb = m_key_bindings.begin (); kb != m_key_bindings.end (); ++kb) { mp_mw->apply_key_bindings ();
if (mp_mw->menu ()->is_valid (kb->first)) { mp_mw->apply_hidden ();
lay::Action *a = mp_mw->menu ()->action (kb->first);
a->set_shortcut (kb->second);
}
}
// apply the custom hidden flags
for (std::vector<std::pair<std::string, bool> >::const_iterator hf = m_menu_items_hidden.begin (); hf != m_menu_items_hidden.end (); ++hf) {
if (mp_mw->menu ()->is_valid (hf->first)) {
lay::Action *a = mp_mw->menu ()->action (hf->first);
a->set_hidden (hf->second);
}
}
} }
void void

View File

@ -249,8 +249,6 @@ private:
tl::DeferredMethod<MacroController> dm_do_sync_with_external_sources; tl::DeferredMethod<MacroController> dm_do_sync_with_external_sources;
tl::DeferredMethod<MacroController> dm_sync_file_watcher; tl::DeferredMethod<MacroController> dm_sync_file_watcher;
tl::DeferredMethod<MacroController> dm_sync_files; tl::DeferredMethod<MacroController> dm_sync_files;
std::vector<std::pair<std::string, std::string> > m_key_bindings;
std::vector<std::pair<std::string, bool> > m_menu_items_hidden;
void sync_implicit_macros (bool ask_before_autorun); void sync_implicit_macros (bool ask_before_autorun);
void add_macro_items_to_menu (lym::MacroCollection &collection, std::set<std::string> &used_names, std::set<std::string> &groups, const db::Technology *tech); void add_macro_items_to_menu (lym::MacroCollection &collection, std::set<std::string> &used_names, std::set<std::string> &groups, const db::Technology *tech);

View File

@ -1192,8 +1192,8 @@ MainWindow::configure (const std::string &name, const std::string &value)
} else if (name == cfg_menu_items_hidden) { } else if (name == cfg_menu_items_hidden) {
std::vector<std::pair<std::string, bool> > hidden = unpack_menu_items_hidden (value); m_hidden = unpack_menu_items_hidden (value);
apply_hidden (hidden); apply_hidden ();
return true; return true;
} else if (name == cfg_initial_technology) { } else if (name == cfg_initial_technology) {
@ -1213,12 +1213,15 @@ MainWindow::configure (const std::string &name, const std::string &value)
} }
void void
MainWindow::apply_hidden (const std::vector<std::pair<std::string, bool> > &hidden) MainWindow::apply_hidden ()
{ {
for (std::vector<std::pair<std::string, bool> >::const_iterator hf = hidden.begin (); hf != hidden.end (); ++hf) { for (std::vector<std::pair<std::string, bool> >::const_iterator hf = m_hidden.begin (); hf != m_hidden.end (); ++hf) {
if (menu ()->is_valid (hf->first)) { lay::AbstractMenuItem *item = menu ()->find_item_exact (hf->first);
lay::Action *a = menu ()->action (hf->first); if (item && item->primary ()) {
a->set_hidden (hf->second); lay::Action *a = item->action ();
if (a) {
a->set_hidden (hf->second);
}
} }
} }
} }
@ -1227,9 +1230,12 @@ void
MainWindow::apply_key_bindings () MainWindow::apply_key_bindings ()
{ {
for (std::vector<std::pair<std::string, std::string> >::const_iterator kb = m_key_bindings.begin (); kb != m_key_bindings.end (); ++kb) { for (std::vector<std::pair<std::string, std::string> >::const_iterator kb = m_key_bindings.begin (); kb != m_key_bindings.end (); ++kb) {
if (menu ()->is_valid (kb->first)) { lay::AbstractMenuItem *item = menu ()->find_item_exact (kb->first);
lay::Action *a = menu ()->action (kb->first); if (item && item->primary ()) {
a->set_shortcut (kb->second); lay::Action *a = item->action ();
if (a) {
a->set_shortcut (kb->second);
}
} }
} }
} }

View File

@ -534,6 +534,16 @@ public:
*/ */
static std::vector<std::string> menu_symbols (); static std::vector<std::string> menu_symbols ();
/**
* @brief For internal use: apply current key bindings
*/
void apply_key_bindings ();
/**
* @brief For internal use: apply hidden menu flags
*/
void apply_hidden ();
/** /**
* @brief Open a new layout in mode 'mode' * @brief Open a new layout in mode 'mode'
* *
@ -770,6 +780,7 @@ private:
double m_default_grid; double m_default_grid;
bool m_default_grids_updated; bool m_default_grids_updated;
std::vector<std::pair<std::string, std::string> > m_key_bindings; std::vector<std::pair<std::string, std::string> > m_key_bindings;
std::vector<std::pair<std::string, bool> > m_hidden;
bool m_new_layout_current_panel; bool m_new_layout_current_panel;
bool m_synchronized_views; bool m_synchronized_views;
bool m_synchronous; bool m_synchronous;
@ -864,8 +875,6 @@ private:
void plugin_removed (lay::PluginDeclaration *cls); void plugin_removed (lay::PluginDeclaration *cls);
void libraries_changed (); void libraries_changed ();
void apply_key_bindings ();
void apply_hidden (const std::vector<std::pair <std::string, bool> > &hidden);
}; };
} }

View File

@ -220,20 +220,22 @@ parse_menu_title (const std::string &s, std::string &title, std::string &shortcu
// AbstractMenuItem implementation // AbstractMenuItem implementation
AbstractMenuItem::AbstractMenuItem (Dispatcher *dispatcher) AbstractMenuItem::AbstractMenuItem (Dispatcher *dispatcher)
: mp_action (new Action ()), mp_dispatcher (dispatcher), m_has_submenu (false), m_remove_on_empty (false) : mp_action (new Action ()), mp_dispatcher (dispatcher), m_has_submenu (false), m_remove_on_empty (false), m_primary (false)
{ {
// ... nothing yet .. // ... nothing yet ..
} }
AbstractMenuItem::AbstractMenuItem (const AbstractMenuItem &item) AbstractMenuItem::AbstractMenuItem (const AbstractMenuItem &item)
: mp_action (new Action ()), mp_dispatcher (item.dispatcher ()), m_has_submenu (false), m_remove_on_empty (false) : mp_action (new Action ()), mp_dispatcher (item.dispatcher ()), m_has_submenu (false), m_remove_on_empty (false), m_primary (false)
{ {
// ... nothing yet .. // ... nothing yet ..
} }
void void
AbstractMenuItem::setup_item (const std::string &pn, const std::string &s, Action *a) AbstractMenuItem::setup_item (const std::string &pn, const std::string &s, Action *a, bool primary)
{ {
m_primary = primary;
m_basename.clear (); m_basename.clear ();
tl::Extractor ex (s.c_str ()); tl::Extractor ex (s.c_str ());
@ -1587,6 +1589,8 @@ AbstractMenu::items (const std::string &path) const
void void
AbstractMenu::insert_item (const std::string &p, const std::string &name, Action *action) AbstractMenu::insert_item (const std::string &p, const std::string &name, Action *action)
{ {
bool primary = true;
tl::Extractor extr (p.c_str ()); tl::Extractor extr (p.c_str ());
while (! extr.at_end ()) { while (! extr.at_end ()) {
@ -1601,7 +1605,8 @@ AbstractMenu::insert_item (const std::string &p, const std::string &name, Action
parent->children.insert (iter, AbstractMenuItem (mp_dispatcher)); parent->children.insert (iter, AbstractMenuItem (mp_dispatcher));
--iter; --iter;
iter->setup_item (parent->name (), name, action); iter->setup_item (parent->name (), name, action, primary);
primary = false;
// find any items with the same name and remove them // find any items with the same name and remove them
for (std::list<AbstractMenuItem>::iterator existing = parent->children.begin (); existing != parent->children.end (); ) { for (std::list<AbstractMenuItem>::iterator existing = parent->children.begin (); existing != parent->children.end (); ) {
@ -1635,7 +1640,7 @@ AbstractMenu::insert_separator (const std::string &p, const std::string &name)
--iter; --iter;
Action *action = new Action (); Action *action = new Action ();
action->set_separator (true); action->set_separator (true);
iter->setup_item (parent->name (), name, action); iter->setup_item (parent->name (), name, action, true);
} }
@ -1655,7 +1660,7 @@ AbstractMenu::insert_menu (const std::string &p, const std::string &name, Action
parent->children.insert (iter, AbstractMenuItem (mp_dispatcher)); parent->children.insert (iter, AbstractMenuItem (mp_dispatcher));
--iter; --iter;
iter->setup_item (parent->name (), name, action); iter->setup_item (parent->name (), name, action, true);
iter->set_has_submenu (); iter->set_has_submenu ();
// find any items with the same name and remove them // find any items with the same name and remove them
@ -1945,7 +1950,7 @@ AbstractMenu::find_item (tl::Extractor &extr)
if (parent) { if (parent) {
parent->children.insert (iter, AbstractMenuItem (mp_dispatcher)); parent->children.insert (iter, AbstractMenuItem (mp_dispatcher));
--iter; --iter;
iter->setup_item (parent->name (), n, new Action ()); iter->setup_item (parent->name (), n, new Action (), true);
iter->set_has_submenu (); iter->set_has_submenu ();
iter->set_remove_on_empty (); iter->set_remove_on_empty ();
iter->set_action_title (ndesc.empty () ? n : ndesc); iter->set_action_title (ndesc.empty () ? n : ndesc);
@ -2055,16 +2060,17 @@ AbstractMenu::get_shortcuts (const std::string &root, std::map<std::string, std:
std::vector<std::string> items = this->items (root); std::vector<std::string> items = this->items (root);
for (std::vector<std::string>::const_iterator i = items.begin (); i != items.end (); ++i) { for (std::vector<std::string>::const_iterator i = items.begin (); i != items.end (); ++i) {
if (i->size () > 0) { if (i->size () > 0) {
if (is_valid (*i) && action (*i)->is_visible ()) { const AbstractMenuItem *item = find_item_exact (*i);
if (is_menu (*i)) { if (item && item->action () && item->action ()->is_visible ()) {
if (item->has_submenu ()) {
// a menu must be listed (so it can be hidden), but does not have a shortcut // a menu must be listed (so it can be hidden), but does not have a shortcut
// but we don't include special menus // but we don't include special menus
if (i->at (0) != '@') { if (i->at (0) != '@') {
bindings.insert (std::make_pair (*i, std::string ())); bindings.insert (std::make_pair (*i, std::string ()));
} }
get_shortcuts (*i, bindings, with_defaults); get_shortcuts (*i, bindings, with_defaults);
} else if (! is_separator (*i)) { } else if (! item->action ()->is_separator () && item->primary ()) {
bindings.insert (std::make_pair (*i, with_defaults ? action (*i)->get_default_shortcut () : action (*i)->get_effective_shortcut ())); bindings.insert (std::make_pair (*i, with_defaults ? item->action ()->get_default_shortcut () : item->action ()->get_effective_shortcut ()));
} }
} }
} }

View File

@ -559,7 +559,7 @@ struct LAYBASIC_PUBLIC AbstractMenuItem
/** /**
* @brief Internal method used to set up the item * @brief Internal method used to set up the item
*/ */
void setup_item (const std::string &pn, const std::string &n, Action *a); void setup_item (const std::string &pn, const std::string &n, Action *a, bool primary);
Dispatcher *dispatcher () const Dispatcher *dispatcher () const
{ {
@ -616,6 +616,11 @@ struct LAYBASIC_PUBLIC AbstractMenuItem
return m_remove_on_empty; return m_remove_on_empty;
} }
bool primary () const
{
return m_primary;
}
std::list <AbstractMenuItem> children; std::list <AbstractMenuItem> children;
private: private:
@ -623,6 +628,7 @@ private:
Dispatcher *mp_dispatcher; Dispatcher *mp_dispatcher;
bool m_has_submenu; bool m_has_submenu;
bool m_remove_on_empty; bool m_remove_on_empty;
bool m_primary;
std::string m_name; std::string m_name;
std::string m_basename; std::string m_basename;
std::set<std::string> m_groups; std::set<std::string> m_groups;
@ -906,6 +912,16 @@ public:
return m_root; return m_root;
} }
/**
* @brief For internal use: gets the AbstractMenuItem for a given path or 0 if the path is not valid (const version)
*/
const AbstractMenuItem *find_item_exact (const std::string &path) const;
/**
* @brief For internal use: gets the AbstractMenuItem for a given path or 0 if the path is not valid
*/
AbstractMenuItem *find_item_exact (const std::string &path);
#if defined(HAVE_QT) #if defined(HAVE_QT)
signals: signals:
/** /**
@ -918,8 +934,6 @@ private:
friend class Action; friend class Action;
std::vector<std::pair<AbstractMenuItem *, std::list<AbstractMenuItem>::iterator> > find_item (tl::Extractor &extr); std::vector<std::pair<AbstractMenuItem *, std::list<AbstractMenuItem>::iterator> > find_item (tl::Extractor &extr);
const AbstractMenuItem *find_item_exact (const std::string &path) const;
AbstractMenuItem *find_item_exact (const std::string &path);
const AbstractMenuItem *find_item_for_action (const Action *action, const AbstractMenuItem *from = 0) const; const AbstractMenuItem *find_item_for_action (const Action *action, const AbstractMenuItem *from = 0) const;
AbstractMenuItem *find_item_for_action (const Action *action, AbstractMenuItem *from = 0); AbstractMenuItem *find_item_for_action (const Action *action, AbstractMenuItem *from = 0);
#if defined(HAVE_QT) #if defined(HAVE_QT)

View File

@ -4084,7 +4084,9 @@ LayoutViewBase::cancel_edits ()
// the move service takes a special role here as it manages the // the move service takes a special role here as it manages the
// transaction for the collective move operation. // transaction for the collective move operation.
mp_move_service->cancel (); if (mp_move_service) {
mp_move_service->cancel ();
}
// cancel all drag and pending edit operations such as move operations. // cancel all drag and pending edit operations such as move operations.
mp_canvas->drag_cancel (); mp_canvas->drag_cancel ();
@ -4099,7 +4101,9 @@ LayoutViewBase::finish_edits ()
{ {
// the move service takes a special role here as it manages the // the move service takes a special role here as it manages the
// transaction for the collective move operation. // transaction for the collective move operation.
mp_move_service->finish (); if (mp_move_service) {
mp_move_service->finish ();
}
// cancel all drag operations // cancel all drag operations
mp_canvas->drag_cancel (); mp_canvas->drag_cancel ();
@ -5460,7 +5464,7 @@ LayoutViewBase::paste_interactive (bool transient_mode)
// operations. // operations.
trans->close (); trans->close ();
if (mp_move_service->begin_move (trans.release (), transient_mode)) { if (mp_move_service && mp_move_service->begin_move (trans.release (), transient_mode)) {
switch_mode (-1); // move mode switch_mode (-1); // move mode
} }
} }

View File

@ -553,7 +553,7 @@ class Box:
""" """
... ...
@overload @overload
def enlarge(self, dx: int, dy: int) -> Box: def enlarge(self, dx: Optional[int] = ..., dy: Optional[int] = ...) -> Box:
r""" r"""
@brief Enlarges the box by a certain amount. @brief Enlarges the box by a certain amount.
@ -596,7 +596,7 @@ class Box:
""" """
... ...
@overload @overload
def enlarged(self, dx: int, dy: int) -> Box: def enlarged(self, dx: Optional[int] = ..., dy: Optional[int] = ...) -> Box:
r""" r"""
@brief Enlarges the box by a certain amount. @brief Enlarges the box by a certain amount.
@ -701,7 +701,7 @@ class Box:
""" """
... ...
@overload @overload
def moved(self, dx, 0: int, dy: Optional[int] = ...) -> Box: def moved(self, dx: Optional[int] = ..., dy: Optional[int] = ...) -> Box:
r""" r"""
@brief Moves the box by a certain distance @brief Moves the box by a certain distance
@ -7407,7 +7407,7 @@ class DBox:
""" """
... ...
@overload @overload
def enlarge(self, dx: float, dy: float) -> DBox: def enlarge(self, dx: Optional[float] = ..., dy: Optional[float] = ...) -> DBox:
r""" r"""
@brief Enlarges the box by a certain amount. @brief Enlarges the box by a certain amount.
@ -7450,7 +7450,7 @@ class DBox:
""" """
... ...
@overload @overload
def enlarged(self, dx: float, dy: float) -> DBox: def enlarged(self, dx: Optional[float] = ..., dy: Optional[float] = ...) -> DBox:
r""" r"""
@brief Enlarges the box by a certain amount. @brief Enlarges the box by a certain amount.
@ -7555,7 +7555,7 @@ class DBox:
""" """
... ...
@overload @overload
def moved(self, dx, 0: float, dy: Optional[float] = ...) -> DBox: def moved(self, dx: Optional[float] = ..., dy: Optional[float] = ...) -> DBox:
r""" r"""
@brief Moves the box by a certain distance @brief Moves the box by a certain distance
@ -30277,10 +30277,9 @@ class Instance:
@brief Gets the complex transformation of the instance or the first instance in the array @brief Gets the complex transformation of the instance or the first instance in the array
This method is always valid compared to \trans, since simple transformations can be expressed as complex transformations as well. This method is always valid compared to \trans, since simple transformations can be expressed as complex transformations as well.
Setter: Setter:
@brief Sets the complex transformation of the instance or the first instance in the array (in micrometer units) @brief Sets the complex transformation of the instance or the first instance in the array
This method sets the transformation the same way as \cplx_trans=, but the displacement of this transformation is given in micrometer units. It is internally translated into database units.
This method has been introduced in version 0.25. This method has been introduced in version 0.23.
""" """
da: DVector da: DVector
r""" r"""
@ -41368,15 +41367,15 @@ class NetPinRef:
@overload @overload
def net(self) -> Net: def net(self) -> Net:
r""" r"""
@brief Gets the net this pin reference is attached to (non-const version). @brief Gets the net this pin reference is attached to.
This constness variant has been introduced in version 0.26.8
""" """
... ...
@overload @overload
def net(self) -> Net: def net(self) -> Net:
r""" r"""
@brief Gets the net this pin reference is attached to. @brief Gets the net this pin reference is attached to (non-const version).
This constness variant has been introduced in version 0.26.8
""" """
... ...
def pin(self) -> Pin: def pin(self) -> Pin:
@ -41666,17 +41665,17 @@ class NetTerminalRef:
@overload @overload
def device(self) -> Device: def device(self) -> Device:
r""" r"""
@brief Gets the device reference. @brief Gets the device reference (non-const version).
Gets the device object that this connection is made to. Gets the device object that this connection is made to.
This constness variant has been introduced in version 0.26.8
""" """
... ...
@overload @overload
def device(self) -> Device: def device(self) -> Device:
r""" r"""
@brief Gets the device reference (non-const version). @brief Gets the device reference.
Gets the device object that this connection is made to. Gets the device object that this connection is made to.
This constness variant has been introduced in version 0.26.8
""" """
... ...
def device_class(self) -> DeviceClass: def device_class(self) -> DeviceClass:
@ -42686,15 +42685,6 @@ class Netlist:
""" """
... ...
@overload @overload
def circuit_by_name(self, name: str) -> Circuit:
r"""
@brief Gets the circuit object for a given name (const version).
If the name is not a valid circuit name, nil is returned.
This constness variant has been introduced in version 0.26.8.
"""
...
@overload
def circuit_by_name(self, name: str) -> Circuit: def circuit_by_name(self, name: str) -> Circuit:
r""" r"""
@brief Gets the circuit object for a given name. @brief Gets the circuit object for a given name.
@ -42702,12 +42692,12 @@ class Netlist:
""" """
... ...
@overload @overload
def circuits_by_name(self, name_pattern: str) -> List[Circuit]: def circuit_by_name(self, name: str) -> Circuit:
r""" r"""
@brief Gets the circuit objects for a given name filter. @brief Gets the circuit object for a given name (const version).
The name filter is a glob pattern. This method will return all \Circuit objects matching the glob pattern. If the name is not a valid circuit name, nil is returned.
This method has been introduced in version 0.26.4. This constness variant has been introduced in version 0.26.8.
""" """
... ...
@overload @overload
@ -42720,6 +42710,15 @@ class Netlist:
This constness variant has been introduced in version 0.26.8. This constness variant has been introduced in version 0.26.8.
""" """
... ...
@overload
def circuits_by_name(self, name_pattern: str) -> List[Circuit]:
r"""
@brief Gets the circuit objects for a given name filter.
The name filter is a glob pattern. This method will return all \Circuit objects matching the glob pattern.
This method has been introduced in version 0.26.4.
"""
...
def combine_devices(self) -> None: def combine_devices(self) -> None:
r""" r"""
@brief Combines devices where possible @brief Combines devices where possible
@ -56566,10 +56565,11 @@ class Shape:
Starting with version 0.23, this method returns nil, if the shape does not represent a box. Starting with version 0.23, this method returns nil, if the shape does not represent a box.
Setter: Setter:
@brief Replaces the shape by the given box (in micrometer units) @brief Replaces the shape by the given box
This method replaces the shape by the given box, like \box= with a \Box argument does. This version translates the box from micrometer units to database units internally. This method replaces the shape by the given box. This method can only be called for editable layouts. It does not change the user properties of the shape.
Calling this method will invalidate any iterators. It should not be called inside a loop iterating over shapes.
This method has been introduced in version 0.25. This method has been introduced in version 0.22.
""" """
box_center: Point box_center: Point
r""" r"""
@ -57238,10 +57238,10 @@ class Shape:
Applies to texts only. Will throw an exception if the object is not a text. Applies to texts only. Will throw an exception if the object is not a text.
Setter: Setter:
@brief Sets the text transformation in micrometer units @brief Sets the text transformation
Applies to texts only. Will throw an exception if the object is not a text. Applies to texts only. Will throw an exception if the object is not a text.
This method has been introduced in version 0.25. This method has been introduced in version 0.23.
""" """
text_valign: int text_valign: int
r""" r"""
@ -60854,16 +60854,16 @@ class SubCircuit(NetlistObject):
@overload @overload
def circuit_ref(self) -> Circuit: def circuit_ref(self) -> Circuit:
r""" r"""
@brief Gets the circuit referenced by the subcircuit (non-const version). @brief Gets the circuit referenced by the subcircuit.
This constness variant has been introduced in version 0.26.8
""" """
... ...
@overload @overload
def circuit_ref(self) -> Circuit: def circuit_ref(self) -> Circuit:
r""" r"""
@brief Gets the circuit referenced by the subcircuit. @brief Gets the circuit referenced by the subcircuit (non-const version).
This constness variant has been introduced in version 0.26.8
""" """
... ...
@overload @overload
@ -61533,8 +61533,7 @@ class Text:
Setter: Setter:
@brief Sets the horizontal alignment @brief Sets the horizontal alignment
This property specifies how the text is aligned relative to the anchor point. This is the version accepting integer values. It's provided for backward compatibility.
This property has been introduced in version 0.22 and extended to enums in 0.28.
""" """
size: int size: int
r""" r"""
@ -61570,8 +61569,7 @@ class Text:
Setter: Setter:
@brief Sets the vertical alignment @brief Sets the vertical alignment
This property specifies how the text is aligned relative to the anchor point. This is the version accepting integer values. It's provided for backward compatibility.
This property has been introduced in version 0.22 and extended to enums in 0.28.
""" """
x: int x: int
r""" r"""

View File

@ -271,6 +271,10 @@ class DBBox_TestClass < TestBase
assert_equal( a.to_s, "(-9,18;12,22)" ) assert_equal( a.to_s, "(-9,18;12,22)" )
a = b.moved( 1, -1 ) a = b.moved( 1, -1 )
assert_equal( a.to_s, "(-9,16;12,20)" ) assert_equal( a.to_s, "(-9,16;12,20)" )
a = b.moved( dy: 1 )
assert_equal( a.to_s, "(-10,18;11,22)" )
a = b.moved( dx: 1 )
assert_equal( a.to_s, "(-9,17;12,21)" )
a = b.dup a = b.dup
a.move( 1, -1 ) a.move( 1, -1 )
@ -304,7 +308,12 @@ class DBBox_TestClass < TestBase
aa = a.dup aa = a.dup
a.enlarge( -1, 1 ) a.enlarge( -1, 1 )
assert_equal( a.to_s, "(-10,21;11,25)" ) assert_equal( a.to_s, "(-10,21;11,25)" )
a.enlarge( 1, -1 )
a.enlarge( dy: 1 )
a.enlarge( dx: -1 )
assert_equal( a.to_s, "(-10,21;11,25)" )
assert_equal( aa.enlarged( -1, 1 ).to_s, "(-10,21;11,25)" ) assert_equal( aa.enlarged( -1, 1 ).to_s, "(-10,21;11,25)" )
assert_equal( aa.enlarged( :dy => 1, :dx => -1 ).to_s, "(-10,21;11,25)" )
a = a.enlarged( RBA::Point::new(1, -1) ) a = a.enlarged( RBA::Point::new(1, -1) )
assert_equal( a.to_s, "(-11,22;12,24)" ) assert_equal( a.to_s, "(-11,22;12,24)" )

View File

@ -2,10 +2,10 @@
# This script is sourced to define the main version parameters # This script is sourced to define the main version parameters
# The main version # The main version
KLAYOUT_VERSION="0.29.9" KLAYOUT_VERSION="0.29.10"
# The version used for PyPI (don't use variables here!) # The version used for PyPI (don't use variables here!)
KLAYOUT_PYPI_VERSION="0.29.9" KLAYOUT_PYPI_VERSION="0.29.10"
# The build date # The build date
KLAYOUT_VERSION_DATE=$(date "+%Y-%m-%d") KLAYOUT_VERSION_DATE=$(date "+%Y-%m-%d")