From c211925d2ad4b88267585a1463436e8ddeee4dc4 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sat, 21 Mar 2026 20:32:32 +0100 Subject: [PATCH] Implemented solution for #2306 First of all, NetlistBrowserDialog#current_path now has a setter. Changing the selection will navigate to the location of the selected object, but not issue an "on_selection_changed" event. In addition, the following features have been added: * NetlistBrowserDialog#db_index * NetlistBrowserDialog#view --- .../layui/gsiDeclLayNetlistBrowserDialog.cc | 32 ++++++++++ src/layui/layui/layIndexedNetlistModel.cc | 60 +++++++++++-------- src/layui/layui/layNetlistBrowserDialog.cc | 14 +++++ src/layui/layui/layNetlistBrowserDialog.h | 15 +++++ src/layui/layui/layNetlistBrowserModel.cc | 4 +- src/layui/layui/layNetlistBrowserPage.cc | 8 +-- src/layui/layui/layNetlistBrowserPage.h | 6 +- 7 files changed, 108 insertions(+), 31 deletions(-) diff --git a/src/layui/layui/gsiDeclLayNetlistBrowserDialog.cc b/src/layui/layui/gsiDeclLayNetlistBrowserDialog.cc index 287f167bc..31eb0113f 100644 --- a/src/layui/layui/gsiDeclLayNetlistBrowserDialog.cc +++ b/src/layui/layui/gsiDeclLayNetlistBrowserDialog.cc @@ -169,6 +169,20 @@ static lay::NetlistObjectPath current_path_second (lay::NetlistBrowserDialog *di return dialog->current_path ().second (); } +static void set_current_path (lay::NetlistBrowserDialog *dialog, const lay::NetlistObjectsPath *path) +{ + if (! path) { + dialog->set_current_path (lay::NetlistObjectsPath ()); + } else { + dialog->set_current_path (*path); + } +} + +static lay::LayoutViewBase *get_view (lay::NetlistBrowserDialog *dialog) +{ + return dialog->view (); +} + Class decl_NetlistBrowserDialog ("lay", "NetlistBrowserDialog", gsi::event ("on_current_db_changed", &lay::NetlistBrowserDialog::current_db_changed_event, "@brief This event is triggered when the current database is changed.\n" @@ -187,6 +201,16 @@ Class decl_NetlistBrowserDialog ("lay", "NetlistBrows gsi::method ("db", &lay::NetlistBrowserDialog::db, "@brief Gets the database the browser is connected to.\n" ) + + gsi::method ("db_index", &lay::NetlistBrowserDialog::l2n_index, + "@brief Gets the database index inside the view the browser is connected to.\n" + "\n" + "This attribute has been introduced in version 0.30.8.\n" + ) + + gsi::method_ext ("view", &get_view, + "@brief Gets the view the browser is connected to.\n" + "\n" + "This attribute has been introduced in version 0.30.8.\n" + ) + gsi::method_ext ("current_path_first", ¤t_path_first, "@brief Gets the path of the current object on the first (layout in case of LVS database) side.\n" ) + @@ -196,6 +220,14 @@ Class decl_NetlistBrowserDialog ("lay", "NetlistBrows gsi::method ("current_path", &lay::NetlistBrowserDialog::current_path, "@brief Gets the path of the current object as a path pair (combines layout and schematic object paths in case of a LVS database view).\n" ) + + gsi::method_ext ("current_path=", &set_current_path, + "@brief Sets the current path.\n" + "This is the setter corresponding to the 'current_path' getter. Passing nil clears the selection.\n" + "Changing the selection will update the highlights and navigate to the location depending on the " + "settings. An \\on_selection_changed signal is not emitted.\n" + "\n" + "This setter has been introduced in version 0.30.8.\n" + ) + gsi::method ("selected_paths", &lay::NetlistBrowserDialog::selected_paths, "@brief Gets the nets currently selected objects (paths) in the netlist database browser.\n" "The result is an array of path pairs. See \\NetlistObjectsPath for details about these pairs." diff --git a/src/layui/layui/layIndexedNetlistModel.cc b/src/layui/layui/layIndexedNetlistModel.cc index f6bd5d6f1..c02de8fff 100644 --- a/src/layui/layui/layIndexedNetlistModel.cc +++ b/src/layui/layui/layIndexedNetlistModel.cc @@ -306,28 +306,28 @@ SingleIndexedNetlistModel::parent_of (const subcircuit_pair &subcircuits) const return std::make_pair (subcircuits.first ? subcircuits.first->circuit () : 0, (const db::Circuit *) 0); } -std::pair > SingleIndexedNetlistModel::top_circuit_from_index(size_t index) const +std::pair > SingleIndexedNetlistModel::top_circuit_from_index (size_t index) const { db::Netlist::const_top_down_circuit_iterator none; return std::make_pair (attr_by_object_and_index (std::make_pair ((const db::Circuit *) 0, (const db::Circuit *) 0), index, mp_netlist->begin_top_down (), mp_netlist->begin_top_down () + mp_netlist->top_circuit_count (), none, none, m_child_circuit_by_circuit_and_index, sort_by_name ()), std::make_pair (db::NetlistCrossReference::None, std::string ())); } -std::pair > SingleIndexedNetlistModel::child_circuit_from_index(const circuit_pair &circuits, size_t index) const +std::pair > SingleIndexedNetlistModel::child_circuit_from_index (const circuit_pair &circuits, size_t index) const { db::Circuit::const_child_circuit_iterator none; return std::make_pair (attr_by_object_and_index (circuits, index, circuits.first->begin_children (), circuits.first->end_children (), none, none, m_child_circuit_by_circuit_and_index, sort_by_name ()), std::make_pair (db::NetlistCrossReference::None, std::string ())); } -std::pair > SingleIndexedNetlistModel::circuit_from_index(size_t index) const +std::pair > SingleIndexedNetlistModel::circuit_from_index (size_t index) const { db::Netlist::const_circuit_iterator none; return std::make_pair (attr_by_object_and_index (std::make_pair (mp_netlist, (const db::Netlist *) 0), index, mp_netlist->begin_circuits (), mp_netlist->end_circuits (), none, none, m_circuit_by_index, sort_by_name ()), std::make_pair (db::NetlistCrossReference::None, std::string ())); } -std::pair > SingleIndexedNetlistModel::net_from_index(const circuit_pair &circuits, size_t index) const +std::pair > SingleIndexedNetlistModel::net_from_index (const circuit_pair &circuits, size_t index) const { db::Circuit::const_net_iterator none; - return std::make_pair (attr_by_object_and_index (circuits, index, circuits.first->begin_nets (), circuits.first->end_nets (), none, none, m_net_by_circuit_and_index, sort_by_expanded_name ()), std::make_pair (db::NetlistCrossReference::None, std::string ())); + return std::make_pair (attr_by_object_and_index (std::make_pair (circuits.first, (const db::Circuit *) 0), index, circuits.first->begin_nets (), circuits.first->end_nets (), none, none, m_net_by_circuit_and_index, sort_by_expanded_name ()), std::make_pair (db::NetlistCrossReference::None, std::string ())); } const db::Net * @@ -346,12 +346,15 @@ IndexedNetlistModel::net_subcircuit_pin_pair SingleIndexedNetlistModel::net_subcircuit_pinref_from_index (const net_pair &nets, size_t index) const { db::Net::const_subcircuit_pin_iterator none; - return attr_by_object_and_index (nets, index, nets.first->begin_subcircuit_pins (), nets.first->end_subcircuit_pins (), none, none, m_subcircuit_pinref_by_net_and_index, sort_by_pin_name ()); + return attr_by_object_and_index (std::make_pair (nets.first, (const db::Net *) 0), index, nets.first->begin_subcircuit_pins (), nets.first->end_subcircuit_pins (), none, none, m_subcircuit_pinref_by_net_and_index, sort_by_pin_name ()); } IndexedNetlistModel::net_subcircuit_pin_pair -SingleIndexedNetlistModel::subcircuit_pinref_from_index (const subcircuit_pair &subcircuits, size_t index) const +SingleIndexedNetlistModel::subcircuit_pinref_from_index (const subcircuit_pair &subcircuits_in, size_t index) const { + subcircuit_pair subcircuits = subcircuits_in; + subcircuits.second = 0; + if (! subcircuits.first) { return IndexedNetlistModel::net_subcircuit_pin_pair ((const db::NetSubcircuitPinRef *) 0, (const db::NetSubcircuitPinRef *) 0); } @@ -381,62 +384,68 @@ IndexedNetlistModel::net_terminal_pair SingleIndexedNetlistModel::net_terminalref_from_index (const net_pair &nets, size_t index) const { db::Net::const_terminal_iterator none; - return attr_by_object_and_index (nets, index, nets.first->begin_terminals (), nets.first->end_terminals (), none, none, m_terminalref_by_net_and_index, sort_by_terminal_id ()); + return attr_by_object_and_index (std::make_pair (nets.first, (const db::Net *) 0), index, nets.first->begin_terminals (), nets.first->end_terminals (), none, none, m_terminalref_by_net_and_index, sort_by_terminal_id ()); } IndexedNetlistModel::net_pin_pair SingleIndexedNetlistModel::net_pinref_from_index (const net_pair &nets, size_t index) const { db::Net::const_pin_iterator none; - return attr_by_object_and_index (nets, index, nets.first->begin_pins (), nets.first->end_pins (), none, none, m_pinref_by_net_and_index, sort_by_pin_name ()); + return attr_by_object_and_index (std::make_pair (nets.first, (const db::Net *) 0), index, nets.first->begin_pins (), nets.first->end_pins (), none, none, m_pinref_by_net_and_index, sort_by_pin_name ()); } -std::pair > SingleIndexedNetlistModel::device_from_index(const circuit_pair &circuits, size_t index) const +std::pair > SingleIndexedNetlistModel::device_from_index (const circuit_pair &circuits, size_t index) const { db::Circuit::const_device_iterator none; - return std::make_pair (attr_by_object_and_index (circuits, index, circuits.first->begin_devices (), circuits.first->end_devices (), none, none, m_device_by_circuit_and_index, sort_by_expanded_name ()), std::make_pair (db::NetlistCrossReference::None, std::string ())); + return std::make_pair (attr_by_object_and_index (std::make_pair (circuits.first, (const db::Circuit *) 0), index, circuits.first->begin_devices (), circuits.first->end_devices (), none, none, m_device_by_circuit_and_index, sort_by_expanded_name ()), std::make_pair (db::NetlistCrossReference::None, std::string ())); } -std::pair > SingleIndexedNetlistModel::pin_from_index(const circuit_pair &circuits, size_t index) const +std::pair > SingleIndexedNetlistModel::pin_from_index (const circuit_pair &circuits, size_t index) const { db::Circuit::const_pin_iterator none; - return std::make_pair (attr_by_object_and_index (circuits, index, circuits.first->begin_pins (), circuits.first->end_pins (), none, none, m_pin_by_circuit_and_index, Unsorted ()), std::make_pair (db::NetlistCrossReference::None, std::string ())); + return std::make_pair (attr_by_object_and_index (std::make_pair (circuits.first, (const db::Circuit *) 0), index, circuits.first->begin_pins (), circuits.first->end_pins (), none, none, m_pin_by_circuit_and_index, Unsorted ()), std::make_pair (db::NetlistCrossReference::None, std::string ())); } -std::pair > SingleIndexedNetlistModel::subcircuit_from_index(const circuit_pair &circuits, size_t index) const +std::pair > SingleIndexedNetlistModel::subcircuit_from_index (const circuit_pair &circuits, size_t index) const { db::Circuit::const_subcircuit_iterator none; - return std::make_pair (attr_by_object_and_index (circuits, index, circuits.first->begin_subcircuits (), circuits.first->end_subcircuits (), none, none, m_subcircuit_by_circuit_and_index, sort_by_expanded_name ()), std::make_pair (db::NetlistCrossReference::None, std::string ())); + return std::make_pair (attr_by_object_and_index (std::make_pair (circuits.first, (const db::Circuit *) 0), index, circuits.first->begin_subcircuits (), circuits.first->end_subcircuits (), none, none, m_subcircuit_by_circuit_and_index, sort_by_expanded_name ()), std::make_pair (db::NetlistCrossReference::None, std::string ())); } size_t SingleIndexedNetlistModel::circuit_index (const circuit_pair &circuits) const { db::Netlist::const_circuit_iterator none; - return index_from_attr (circuits, mp_netlist->begin_circuits (), mp_netlist->end_circuits (), none, none, m_circuit_index_by_object, sort_by_name ()); + return index_from_attr (std::make_pair (circuits.first, (const db::Circuit *) 0), mp_netlist->begin_circuits (), mp_netlist->end_circuits (), none, none, m_circuit_index_by_object, sort_by_name ()); } size_t -SingleIndexedNetlistModel::net_index (const net_pair &nets) const +SingleIndexedNetlistModel::net_index (const net_pair &nets_in) const { db::Circuit::const_net_iterator none; + net_pair nets = nets_in; + nets.second = 0; + circuit_pair circuits = parent_of (nets); return index_from_attr (nets, circuits.first ? circuits.first->begin_nets () : none, circuits.first ? circuits.first->end_nets () : none, - circuits.second ? circuits.second->begin_nets () : none, circuits.second ? circuits.second->end_nets () : none, + none, none, m_net_index_by_object, sort_by_expanded_name ()); } size_t -SingleIndexedNetlistModel::device_index (const device_pair &devices) const +SingleIndexedNetlistModel::device_index (const device_pair &devices_in) const { db::Circuit::const_device_iterator none; + device_pair devices = devices_in; + devices.second = 0; + circuit_pair circuits = parent_of (devices); return index_from_attr (devices, circuits.first ? circuits.first->begin_devices () : none, circuits.first ? circuits.first->end_devices () : none, - circuits.second ? circuits.second->begin_devices () : none, circuits.second ? circuits.second->end_devices () : none, + none, none, m_device_index_by_object, sort_by_expanded_name ()); } @@ -445,21 +454,24 @@ SingleIndexedNetlistModel::pin_index (const pin_pair &pins, const circuit_pair & { db::Circuit::const_pin_iterator none; - return index_from_attr (pins, + return index_from_attr (std::make_pair (pins.first, (const db::Pin *) 0), circuits.first ? circuits.first->begin_pins () : none, circuits.first ? circuits.first->end_pins () : none, - circuits.second ? circuits.second->begin_pins () : none, circuits.second ? circuits.second->end_pins () : none, + none, none, m_pin_index_by_object, sort_by_expanded_name ()); } size_t -SingleIndexedNetlistModel::subcircuit_index (const subcircuit_pair &subcircuits) const +SingleIndexedNetlistModel::subcircuit_index (const subcircuit_pair &subcircuits_in) const { db::Circuit::const_subcircuit_iterator none; + subcircuit_pair subcircuits = subcircuits_in; + subcircuits.second = 0; + circuit_pair circuits = parent_of (subcircuits); return index_from_attr (subcircuits, circuits.first ? circuits.first->begin_subcircuits () : none, circuits.first ? circuits.first->end_subcircuits () : none, - circuits.second ? circuits.second->begin_subcircuits () : none, circuits.second ? circuits.second->end_subcircuits () : none, + none, none, m_subcircuit_index_by_object, sort_by_expanded_name ()); } diff --git a/src/layui/layui/layNetlistBrowserDialog.cc b/src/layui/layui/layNetlistBrowserDialog.cc index ddc23f542..680336685 100644 --- a/src/layui/layui/layNetlistBrowserDialog.cc +++ b/src/layui/layui/layNetlistBrowserDialog.cc @@ -141,6 +141,12 @@ NetlistBrowserDialog::db () return mp_ui->browser_page->db (); } +int +NetlistBrowserDialog::l2n_index () +{ + return m_l2n_index; +} + const lay::NetlistObjectsPath & NetlistBrowserDialog::current_path () const { @@ -152,6 +158,14 @@ NetlistBrowserDialog::current_path () const } } +void +NetlistBrowserDialog::set_current_path (const lay::NetlistObjectsPath &path) +{ + if (mp_ui->browser_page) { + mp_ui->browser_page->select_path (path); + } +} + const std::vector & NetlistBrowserDialog::selected_paths () const { diff --git a/src/layui/layui/layNetlistBrowserDialog.h b/src/layui/layui/layNetlistBrowserDialog.h index 92635cd6d..069aa2aff 100644 --- a/src/layui/layui/layNetlistBrowserDialog.h +++ b/src/layui/layui/layNetlistBrowserDialog.h @@ -77,11 +77,26 @@ public: */ db::LayoutToNetlist *db (); + /** + * @brief Gets the index of the currently selected database in the view + */ + int l2n_index (); + /** * @brief Gets the current object's path */ const lay::NetlistObjectsPath ¤t_path () const; + /** + * @brief Sets the current object's path + * + * This will make the given netlist object the current one and change the + * selection to this one. + * + * Passing a null path will clear the selection. + */ + void set_current_path (const lay::NetlistObjectsPath &path); + /** * @brief Gets the selected nets */ diff --git a/src/layui/layui/layNetlistBrowserModel.cc b/src/layui/layui/layNetlistBrowserModel.cc index 3a0934bb1..e61c7b35c 100644 --- a/src/layui/layui/layNetlistBrowserModel.cc +++ b/src/layui/layui/layNetlistBrowserModel.cc @@ -3025,9 +3025,9 @@ NetlistBrowserModel::index_from_subcircuit (const std::pairsecond_circuit_for (net))); + return index_from_circuit (std::make_pair (circuit, mp_indexer->second_circuit_for (circuit))); } std::pair diff --git a/src/layui/layui/layNetlistBrowserPage.cc b/src/layui/layui/layNetlistBrowserPage.cc index 4c83a9634..5543c94e4 100644 --- a/src/layui/layui/layNetlistBrowserPage.cc +++ b/src/layui/layui/layNetlistBrowserPage.cc @@ -502,9 +502,9 @@ NetlistBrowserPage::select_path (const lay::NetlistObjectsPath &path) { if (path.is_null ()) { - nl_directory_tree->clearSelection (); - sch_directory_tree->clearSelection (); - xref_directory_tree->clearSelection (); + nl_directory_tree->setCurrentIndex (QModelIndex ()); + sch_directory_tree->setCurrentIndex (QModelIndex ()); + xref_directory_tree->setCurrentIndex (QModelIndex ()); } else { @@ -1315,7 +1315,7 @@ NetlistBrowserPage::clear_highlights () void NetlistBrowserPage::highlight (const NetlistObjectsPath ¤t_path, const std::vector &selected_paths) { - if (current_path != m_current_path && selected_paths != m_selected_paths) { + if (current_path != m_current_path || selected_paths != m_selected_paths) { m_current_path = current_path; m_selected_paths = selected_paths; diff --git a/src/layui/layui/layNetlistBrowserPage.h b/src/layui/layui/layNetlistBrowserPage.h index 69c9fa32f..dbbdd24bd 100644 --- a/src/layui/layui/layNetlistBrowserPage.h +++ b/src/layui/layui/layNetlistBrowserPage.h @@ -169,6 +169,11 @@ public: */ void update_highlights (); + /** + * @brief Adjusts the view depending on the current settings + */ + void adjust_view (); + /** * @brief Gets the current object's path */ @@ -255,7 +260,6 @@ private: void setup_trees (); void add_to_history (const QModelIndex &index, bool fwd); void navigate_to (const QModelIndex &index, bool forward = true); - void adjust_view (); void clear_markers (); void highlight (const NetlistObjectsPath ¤t_path, const std::vector &selected_paths); void clear_highlights ();