diff --git a/src/db/db/dbCircuit.h b/src/db/db/dbCircuit.h index d905cc300..1f7a02eed 100644 --- a/src/db/db/dbCircuit.h +++ b/src/db/db/dbCircuit.h @@ -41,6 +41,42 @@ namespace db class Netlist; +/** + * @brief An iterator wrapper for the child and parent circuit iterator + */ +template +struct DB_PUBLIC_TEMPLATE dereferencing_iterator + : public Iter +{ +public: + typedef Value *pointer; + typedef Value &reference; + typedef typename Iter::difference_type difference_type; + + dereferencing_iterator () { } + dereferencing_iterator (const dereferencing_iterator &d) : Iter (d) { } + dereferencing_iterator (const Iter &d) : Iter (d) { } + dereferencing_iterator &operator= (const dereferencing_iterator &d) + { + Iter::operator= (d); + return *this; + } + + dereferencing_iterator operator+ (difference_type offset) const + { + return dereferencing_iterator (Iter::operator+ (offset)); + } + + dereferencing_iterator &operator+= (difference_type offset) + { + Iter::operator+= (offset); + return *this; + } + + pointer operator-> () const { return Iter::operator* (); } + reference operator* () const { return *Iter::operator* (); } +}; + /** * @brief A circuit * @@ -65,10 +101,10 @@ public: typedef subcircuit_list::iterator subcircuit_iterator; typedef tl::weak_collection::const_iterator const_refs_iterator; typedef tl::weak_collection::iterator refs_iterator; - typedef tl::vector::const_iterator child_circuit_iterator; - typedef tl::vector::const_iterator const_child_circuit_iterator; - typedef tl::vector::const_iterator parent_circuit_iterator; - typedef tl::vector::const_iterator const_parent_circuit_iterator; + typedef dereferencing_iterator::const_iterator, Circuit> child_circuit_iterator; + typedef dereferencing_iterator::const_iterator, const Circuit> const_child_circuit_iterator; + typedef dereferencing_iterator::const_iterator, Circuit> parent_circuit_iterator; + typedef dereferencing_iterator::const_iterator, const Circuit> const_parent_circuit_iterator; /** * @brief Constructor diff --git a/src/db/db/dbLayoutToNetlistWriter.cc b/src/db/db/dbLayoutToNetlistWriter.cc index 1e19c5cef..511c581d8 100644 --- a/src/db/db/dbLayoutToNetlistWriter.cc +++ b/src/db/db/dbLayoutToNetlistWriter.cc @@ -184,7 +184,7 @@ void std_writer_impl::write (const db::Netlist *nl, const db::LayoutToNetl *mp_stream << indent << "# Circuits are the hierarchical building blocks of the netlist." << endl; } for (db::Netlist::const_bottom_up_circuit_iterator i = nl->begin_bottom_up (); i != nl->end_bottom_up (); ++i) { - const db::Circuit *x = *i; + const db::Circuit *x = i.operator-> (); *mp_stream << indent << Keys::circuit_key << "(" << tl::to_word_or_quoted_string (x->name ()) << endl; write (nl, l2n, *x, indent, net2id_per_circuit); *mp_stream << indent << ")" << endl; diff --git a/src/db/db/dbNetlist.cc b/src/db/db/dbNetlist.cc index ea1359b44..bfc6ca603 100644 --- a/src/db/db/dbNetlist.cc +++ b/src/db/db/dbNetlist.cc @@ -435,7 +435,7 @@ void Netlist::make_top_level_pins () size_t ntop = top_circuit_count (); for (top_down_circuit_iterator c = begin_top_down (); c != end_top_down () && ntop > 0; ++c, --ntop) { - Circuit *circuit = *c; + Circuit *circuit = c.operator-> (); if (circuit->pin_count () == 0) { @@ -460,7 +460,7 @@ void Netlist::purge () for (bottom_up_circuit_iterator c = begin_bottom_up (); c != end_bottom_up (); ++c) { - Circuit *circuit = *c; + Circuit *circuit = c.operator-> (); circuit->purge_nets (); if (circuit->begin_nets () == circuit->end_nets ()) { diff --git a/src/db/db/dbNetlist.h b/src/db/db/dbNetlist.h index 3dd848b86..a932cc8a6 100644 --- a/src/db/db/dbNetlist.h +++ b/src/db/db/dbNetlist.h @@ -55,10 +55,10 @@ public: typedef tl::shared_collection device_abstract_list; typedef device_abstract_list::const_iterator const_abstract_model_iterator; typedef device_abstract_list::iterator device_abstract_iterator; - typedef tl::vector::const_iterator top_down_circuit_iterator; - typedef tl::vector::const_iterator const_top_down_circuit_iterator; - typedef tl::vector::const_reverse_iterator bottom_up_circuit_iterator; - typedef tl::vector::const_reverse_iterator const_bottom_up_circuit_iterator; + typedef dereferencing_iterator::iterator, Circuit> top_down_circuit_iterator; + typedef dereferencing_iterator::const_iterator, const Circuit> const_top_down_circuit_iterator; + typedef dereferencing_iterator::reverse_iterator, Circuit> bottom_up_circuit_iterator; + typedef dereferencing_iterator::const_reverse_iterator, const Circuit> const_bottom_up_circuit_iterator; /** * @brief Constructor diff --git a/src/db/db/dbNetlistCompare.cc b/src/db/db/dbNetlistCompare.cc index c1aae1fe2..3e1cb930b 100644 --- a/src/db/db/dbNetlistCompare.cc +++ b/src/db/db/dbNetlistCompare.cc @@ -1733,7 +1733,7 @@ NetlistComparer::compare (const db::Netlist *a, const db::Netlist *b) const for (db::Netlist::const_bottom_up_circuit_iterator c = a->begin_bottom_up (); c != a->end_bottom_up (); ++c) { - size_t ccat = circuit_categorizer.cat_for_circuit (*c); + size_t ccat = circuit_categorizer.cat_for_circuit (c.operator-> ()); std::map >::const_iterator i = cat2circuits.find (ccat); tl_assert (i != cat2circuits.end ()); diff --git a/src/db/db/dbNetlistSpiceWriter.cc b/src/db/db/dbNetlistSpiceWriter.cc index 2f6334877..654855e49 100644 --- a/src/db/db/dbNetlistSpiceWriter.cc +++ b/src/db/db/dbNetlistSpiceWriter.cc @@ -370,7 +370,7 @@ void NetlistSpiceWriter::do_write (const std::string &description) for (db::Netlist::const_top_down_circuit_iterator c = mp_netlist->begin_top_down (); c != mp_netlist->end_top_down (); ++c) { - const db::Circuit &circuit = **c; + const db::Circuit &circuit = *c; // assign internal node numbers to the nets m_net_to_spice_id.clear (); diff --git a/src/db/unit_tests/dbNetlistTests.cc b/src/db/unit_tests/dbNetlistTests.cc index 9d121cd9a..6ed838c41 100644 --- a/src/db/unit_tests/dbNetlistTests.cc +++ b/src/db/unit_tests/dbNetlistTests.cc @@ -191,7 +191,7 @@ static std::string children2string (const db::Circuit *c) if (!res.empty ()) { res += ","; } - res += (*r)->name (); + res += r->name (); } return res; } @@ -203,7 +203,7 @@ static std::string parents2string (const db::Circuit *c) if (!res.empty ()) { res += ","; } - res += (*r)->name (); + res += r->name (); } return res; } @@ -215,7 +215,7 @@ static std::string td2string (const db::Netlist *nl) if (!res.empty ()) { res += ","; } - res += (*r)->name (); + res += r->name (); } return res; } @@ -227,7 +227,7 @@ static std::string bu2string (const db::Netlist *nl) if (!res.empty ()) { res += ","; } - res += (*r)->name (); + res += r->name (); } return res; } diff --git a/src/laybasic/laybasic/NetlistBrowserPage.ui b/src/laybasic/laybasic/NetlistBrowserPage.ui index 309d098d8..4fc9a5289 100644 --- a/src/laybasic/laybasic/NetlistBrowserPage.ui +++ b/src/laybasic/laybasic/NetlistBrowserPage.ui @@ -204,49 +204,95 @@ - + - + 0 - 0 + 1 - - - 0 - 4 - + + QFrame::NoFrame - - Qt::ActionsContextMenu + + QFrame::Raised - - QAbstractItemView::ExtendedSelection - - - QAbstractItemView::SelectRows - - - true - - - true - - - true - - - false - - - false - - - false - - - false - + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Qt::Horizontal + + + + + 0 + 0 + + + + 100 + + + + + + 1 + 0 + + + + + 0 + 0 + + + + Qt::ActionsContextMenu + + + QAbstractItemView::ExtendedSelection + + + QAbstractItemView::SelectRows + + + true + + + true + + + true + + + false + + + false + + + false + + + false + + + + + @@ -338,6 +384,12 @@ + backward + forward + info_button + find_text + find_button + hierarchy_tree directory_tree diff --git a/src/laybasic/laybasic/layIndexedNetlistModel.cc b/src/laybasic/laybasic/layIndexedNetlistModel.cc index be78b40f6..522bbae61 100644 --- a/src/laybasic/laybasic/layIndexedNetlistModel.cc +++ b/src/laybasic/laybasic/layIndexedNetlistModel.cc @@ -272,15 +272,15 @@ SingleIndexedNetlistModel::parent_of (const subcircuit_pair &subcircuits) const std::pair SingleIndexedNetlistModel::top_circuit_from_index (size_t index) const { - const db::Circuit *c = mp_netlist->begin_top_down () [index]; - return std::make_pair (std::make_pair (c, (const db::Circuit *) 0), db::NetlistCrossReference::None); + 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 ()), db::NetlistCrossReference::None); } std::pair SingleIndexedNetlistModel::child_circuit_from_index (const circuit_pair &circuits, size_t index) const { - const db::Circuit *c = circuits.first->begin_children () [index]; - return std::make_pair (std::make_pair (c, (const db::Circuit *) 0), db::NetlistCrossReference::None); + 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 ()), db::NetlistCrossReference::None); } std::pair @@ -303,6 +303,12 @@ SingleIndexedNetlistModel::second_net_for (const db::Net * /*first*/) const return 0; } +const db::Circuit * +SingleIndexedNetlistModel::second_circuit_for (const db::Circuit * /*first*/) const +{ + return 0; +} + IndexedNetlistModel::net_subcircuit_pin_pair SingleIndexedNetlistModel::net_subcircuit_pinref_from_index (const net_pair &nets, size_t index) const { diff --git a/src/laybasic/laybasic/layIndexedNetlistModel.h b/src/laybasic/laybasic/layIndexedNetlistModel.h index 8e347b260..db11b3d47 100644 --- a/src/laybasic/laybasic/layIndexedNetlistModel.h +++ b/src/laybasic/laybasic/layIndexedNetlistModel.h @@ -90,6 +90,7 @@ public: virtual std::pair circuit_from_index (size_t index) const = 0; virtual std::pair net_from_index (const circuit_pair &circuits, size_t index) const = 0; virtual const db::Net *second_net_for (const db::Net *first) const = 0; + virtual const db::Circuit *second_circuit_for (const db::Circuit *first) const = 0; virtual net_subcircuit_pin_pair net_subcircuit_pinref_from_index (const net_pair &nets, size_t index) const = 0; virtual net_terminal_pair net_terminalref_from_index (const net_pair &nets, size_t index) const = 0; virtual net_pin_pair net_pinref_from_index (const net_pair &nets, size_t index) const = 0; @@ -147,7 +148,8 @@ public: virtual std::pair circuit_from_index (size_t index) const; virtual std::pair child_circuit_from_index (const circuit_pair &circuits, size_t index) const; virtual std::pair net_from_index (const circuit_pair &circuits, size_t index) const; - virtual const db::Net *second_net_for (const db::Net * /*first*/) const; + virtual const db::Net *second_net_for (const db::Net *first) const; + virtual const db::Circuit *second_circuit_for (const db::Circuit *first) const; virtual net_subcircuit_pin_pair net_subcircuit_pinref_from_index (const net_pair &nets, size_t index) const; virtual net_terminal_pair net_terminalref_from_index (const net_pair &nets, size_t index) const; virtual net_pin_pair net_pinref_from_index (const net_pair &nets, size_t index) const; @@ -167,6 +169,7 @@ private: const db::Netlist *mp_netlist; mutable std::map > m_circuit_by_index; + mutable std::map > m_child_circuit_by_circuit_and_index; mutable std::map > m_net_by_circuit_and_index; mutable std::map > m_subcircuit_pinref_by_net_and_index; mutable std::map > m_terminalref_by_net_and_index; diff --git a/src/laybasic/laybasic/layNetlistBrowserModel.cc b/src/laybasic/laybasic/layNetlistBrowserModel.cc index 82cd7b1a6..b9e1e2639 100644 --- a/src/laybasic/laybasic/layNetlistBrowserModel.cc +++ b/src/laybasic/laybasic/layNetlistBrowserModel.cc @@ -1911,6 +1911,25 @@ NetlistBrowserModel::index_from_net (const db::Net *net) const return index_from_net (std::make_pair (net, mp_indexer->second_net_for (net))); } +QModelIndex +NetlistBrowserModel::index_from_circuit (const std::pair &circuits) const +{ + void *id = make_id_circuit (mp_indexer->circuit_index (circuits)); + return index_from_id (id, 0); +} + +QModelIndex +NetlistBrowserModel::index_from_circuit (const db::Circuit *net) const +{ + return index_from_circuit (std::make_pair (net, mp_indexer->second_circuit_for (net))); +} + +std::pair +NetlistBrowserModel::circuit_from_index (const QModelIndex &index) const +{ + return circuits_from_id (index.internalPointer ()); +} + std::pair NetlistBrowserModel::net_from_index (const QModelIndex &index) const { diff --git a/src/laybasic/laybasic/layNetlistBrowserModel.h b/src/laybasic/laybasic/layNetlistBrowserModel.h index 07ea3dd12..72556eeb0 100644 --- a/src/laybasic/laybasic/layNetlistBrowserModel.h +++ b/src/laybasic/laybasic/layNetlistBrowserModel.h @@ -135,6 +135,9 @@ public: std::pair net_from_index (const QModelIndex &index) const; QModelIndex index_from_net (const std::pair &net) const; QModelIndex index_from_net (const db::Net *net) const; + std::pair circuit_from_index (const QModelIndex &index) const; + QModelIndex index_from_circuit (const std::pair &circuit) const; + QModelIndex index_from_circuit (const db::Circuit *circuit) const; std::pair subcircuit_from_index (const QModelIndex &index) const; diff --git a/src/laybasic/laybasic/layNetlistBrowserPage.cc b/src/laybasic/laybasic/layNetlistBrowserPage.cc index d6f624e84..655ee9171 100644 --- a/src/laybasic/laybasic/layNetlistBrowserPage.cc +++ b/src/laybasic/laybasic/layNetlistBrowserPage.cc @@ -23,6 +23,7 @@ #include "layNetlistBrowserPage.h" #include "layNetlistBrowserModel.h" +#include "layNetlistBrowserTreeModel.h" #include "layItemDelegates.h" #include "layCellView.h" #include "layLayoutView.h" @@ -153,6 +154,14 @@ NetlistBrowserPage::NetlistBrowserPage (QWidget * /*parent*/) directory_tree->setItemDelegateForColumn (i, delegate); } + for (int i = 0; i < 2; ++i) { + delegate = new lay::HTMLItemDelegate (this); + delegate->set_text_margin (2); + delegate->set_anchors_clickable (true); + connect (delegate, SIGNAL (anchor_clicked (const QString &)), this, SLOT (anchor_clicked (const QString &))); + hierarchy_tree->setItemDelegateForColumn (i, delegate); + } + QMenu *find_edit_menu = new QMenu (find_text); find_edit_menu->addAction (actionUseRegularExpressions); find_edit_menu->addAction (actionCaseSensitive); @@ -284,14 +293,48 @@ NetlistBrowserPage::anchor_clicked (const QString &a) navigate_to (id, true); } +void +NetlistBrowserPage::current_tree_index_changed (const QModelIndex &index) +{ + if (index.isValid () && m_signals_enabled) { + + NetlistBrowserTreeModel *tree_model = dynamic_cast (hierarchy_tree->model ()); + NetlistBrowserModel *netlist_model = dynamic_cast (directory_tree->model ()); + if (! tree_model || ! netlist_model) { + return; + } + + std::pair circuits = tree_model->circuits_from_index (index); + QModelIndex circuit_index = netlist_model->index_from_circuit (circuits); + + m_signals_enabled = false; + directory_tree->setCurrentIndex (circuit_index); + m_signals_enabled = true; + + } +} + void NetlistBrowserPage::current_index_changed (const QModelIndex &index) { if (index.isValid () && m_signals_enabled) { + NetlistBrowserTreeModel *tree_model = dynamic_cast (hierarchy_tree->model ()); + NetlistBrowserModel *netlist_model = dynamic_cast (directory_tree->model ()); + if (! tree_model || ! netlist_model) { + return; + } + void *id = index.internalPointer (); add_to_history (id, true); + std::pair circuits = netlist_model->circuit_from_index (index); + QModelIndex circuit_index = tree_model->index_from_circuits (circuits); + + m_signals_enabled = false; + hierarchy_tree->setCurrentIndex (circuit_index); + m_signals_enabled = true; + } } @@ -424,19 +467,26 @@ NetlistBrowserPage::select_color_for_net () void NetlistBrowserPage::navigate_to (void *id, bool fwd) { - NetlistBrowserModel *model = dynamic_cast (directory_tree->model ()); - if (! model) { + NetlistBrowserTreeModel *tree_model = dynamic_cast (hierarchy_tree->model ()); + NetlistBrowserModel *netlist_model = dynamic_cast (directory_tree->model ()); + if (! tree_model || ! netlist_model) { return; } - QModelIndex index = model->index_from_id (id, 0); + QModelIndex index = netlist_model->index_from_id (id, 0); if (! index.isValid ()) { return; } m_signals_enabled = false; try { + directory_tree->setCurrentIndex (index); + + std::pair circuits = netlist_model->circuit_from_index (index); + QModelIndex circuit_index = tree_model->index_from_circuits (circuits); + hierarchy_tree->setCurrentIndex (circuit_index); + } catch (...) { } m_signals_enabled = true; @@ -636,43 +686,78 @@ NetlistBrowserPage::set_db (db::LayoutToNetlist *l2ndb) if (! mp_database.get ()) { delete directory_tree->model (); directory_tree->setModel (0); + delete hierarchy_tree->model (); + hierarchy_tree->setModel (0); return; } m_cell_context_cache = db::ContextCache (mp_database->internal_layout ()); - // NOTE: with the tree as the parent, the tree will take over ownership of the model - NetlistBrowserModel *new_model = 0; - if (lvsdb) { - new_model = new NetlistBrowserModel (directory_tree, lvsdb, &m_colorizer); - } else { - new_model = new NetlistBrowserModel (directory_tree, l2ndb, &m_colorizer); - } - - int columns = directory_tree->model () ? directory_tree->model ()->columnCount (QModelIndex ()) : 0; - int new_columns = new_model->columnCount (QModelIndex ()); - - delete directory_tree->model (); - directory_tree->setModel (new_model); - connect (directory_tree->selectionModel (), SIGNAL (currentChanged (const QModelIndex &, const QModelIndex &)), this, SLOT (current_index_changed (const QModelIndex &))); - connect (directory_tree->selectionModel (), SIGNAL (selectionChanged (const QItemSelection &, const QItemSelection &)), this, SLOT (selection_changed ())); - - directory_tree->header ()->show (); - directory_tree->header ()->setStretchLastSection (true); - directory_tree->header ()->setMinimumSectionSize (25); - - if (columns < new_columns) { - // makes sure new columns are properly size-adjusted - for (int i = std::max (0, columns - 1); i < new_columns; ++i) { - directory_tree->header ()->resizeSection (i, i == 1 ? directory_tree->header ()->minimumSectionSize () : directory_tree->header ()->defaultSectionSize ()); + { + // NOTE: with the tree as the parent, the tree will take over ownership of the model + NetlistBrowserModel *new_model = 0; + if (lvsdb) { + new_model = new NetlistBrowserModel (directory_tree, lvsdb, &m_colorizer); + } else { + new_model = new NetlistBrowserModel (directory_tree, l2ndb, &m_colorizer); } + + int columns = directory_tree->model () ? directory_tree->model ()->columnCount (QModelIndex ()) : 0; + int new_columns = new_model->columnCount (QModelIndex ()); + + delete directory_tree->model (); + directory_tree->setModel (new_model); + connect (directory_tree->selectionModel (), SIGNAL (currentChanged (const QModelIndex &, const QModelIndex &)), this, SLOT (current_index_changed (const QModelIndex &))); + connect (directory_tree->selectionModel (), SIGNAL (selectionChanged (const QItemSelection &, const QItemSelection &)), this, SLOT (selection_changed ())); + + directory_tree->header ()->show (); + directory_tree->header ()->setStretchLastSection (true); + directory_tree->header ()->setMinimumSectionSize (25); + + if (columns < new_columns) { + // makes sure new columns are properly size-adjusted + for (int i = std::max (0, columns - 1); i < new_columns; ++i) { + directory_tree->header ()->resizeSection (i, i == 1 ? directory_tree->header ()->minimumSectionSize () : directory_tree->header ()->defaultSectionSize ()); + } + } + + // hide the status column if not needed + directory_tree->header ()->setSectionHidden (1, new_model->status_column () < 0); + + // establish visibility according to "show all" + new_model->set_item_visibility (directory_tree, m_show_all, false /*show warnings only with 'show all'*/); } - // hide the status column if not needed - directory_tree->header ()->setSectionHidden (1, new_model->status_column () < 0); + { + // NOTE: with the tree as the parent, the tree will take over ownership of the model + NetlistBrowserTreeModel *new_hierarchy_model = 0; + if (lvsdb) { + new_hierarchy_model = new NetlistBrowserTreeModel (hierarchy_tree, lvsdb); + } else { + new_hierarchy_model = new NetlistBrowserTreeModel (hierarchy_tree, l2ndb); + } - // establish visibility according to "show all" - new_model->set_item_visibility (directory_tree, m_show_all, false /*show warnings only with 'show all'*/); + int columns = hierarchy_tree->model () ? hierarchy_tree->model ()->columnCount (QModelIndex ()) : 0; + int new_columns = new_hierarchy_model->columnCount (QModelIndex ()); + + delete hierarchy_tree->model (); + hierarchy_tree->setModel (new_hierarchy_model); + connect (hierarchy_tree->selectionModel (), SIGNAL (currentChanged (const QModelIndex &, const QModelIndex &)), this, SLOT (current_tree_index_changed (const QModelIndex &))); + + hierarchy_tree->header ()->show (); + hierarchy_tree->header ()->setStretchLastSection (true); + hierarchy_tree->header ()->setMinimumSectionSize (25); + + if (columns < new_columns) { + // makes sure new columns are properly size-adjusted + for (int i = std::max (0, columns - 1); i < new_columns; ++i) { + hierarchy_tree->header ()->resizeSection (i, i == 1 ? hierarchy_tree->header ()->minimumSectionSize () : hierarchy_tree->header ()->defaultSectionSize ()); + } + } + + // hide the status column if not needed + hierarchy_tree->header ()->setSectionHidden (1, new_hierarchy_model->status_column () < 0); + } find_text->setText (QString ()); } diff --git a/src/laybasic/laybasic/layNetlistBrowserPage.h b/src/laybasic/laybasic/layNetlistBrowserPage.h index 970049654..33ac4bec8 100644 --- a/src/laybasic/laybasic/layNetlistBrowserPage.h +++ b/src/laybasic/laybasic/layNetlistBrowserPage.h @@ -169,6 +169,7 @@ private slots: void navigate_back (); void navigate_forward (); void current_index_changed (const QModelIndex &index); + void current_tree_index_changed (const QModelIndex &index); void selection_changed (); void browse_color_for_net (); void select_color_for_net (); diff --git a/src/laybasic/laybasic/layNetlistBrowserTreeModel.cc b/src/laybasic/laybasic/layNetlistBrowserTreeModel.cc index 8af3fe397..f2e3b9bd9 100644 --- a/src/laybasic/laybasic/layNetlistBrowserTreeModel.cc +++ b/src/laybasic/laybasic/layNetlistBrowserTreeModel.cc @@ -202,7 +202,7 @@ NetlistBrowserTreeModel::search_text (const QModelIndex &index) const } std::pair, db::NetlistCrossReference::Status> -NetlistBrowserTreeModel::cp_status_from_index (const QModelIndex &index, size_t &nprod, size_t &nlast) const +NetlistBrowserTreeModel::cp_status_from_index (const QModelIndex &index, size_t &nprod, size_t &nlast, size_t &nnlast) const { typedef std::pair, db::NetlistCrossReference::Status> cp_status; @@ -210,6 +210,7 @@ NetlistBrowserTreeModel::cp_status_from_index (const QModelIndex &index, size_t tl_assert (id != 0); nprod = 1; + nnlast = 1; nlast = mp_indexer->top_circuit_count () + 1; size_t i = pop (id, nlast); @@ -217,6 +218,7 @@ NetlistBrowserTreeModel::cp_status_from_index (const QModelIndex &index, size_t cp_status cps = mp_indexer->top_circuit_from_index (i - 1); while (id != 0) { + nnlast = nlast; nlast = mp_indexer->child_circuit_count (cps.first) + 1; i = pop (id, nlast); nprod *= nlast; @@ -229,15 +231,58 @@ NetlistBrowserTreeModel::cp_status_from_index (const QModelIndex &index, size_t std::pair NetlistBrowserTreeModel::circuits_from_index (const QModelIndex &index) const { - size_t nprod = 0, nlast = 0; - return cp_status_from_index (index, nprod, nlast).first; + size_t nprod = 0, nlast = 0, nnlast = 0; + return cp_status_from_index (index, nprod, nlast, nnlast).first; } +void +NetlistBrowserTreeModel::build_circuits_to_index (size_t nprod, const std::pair &circuits, IndexedNetlistModel *model, const QModelIndex &index, std::map, QModelIndex> &map) const +{ + if (map.find (circuits) != map.end ()) { + return; + } + + map.insert (std::make_pair (circuits, index)); + + size_t count = mp_indexer->child_circuit_count (circuits); + size_t child_nprod = nprod * (count + 1); + + for (size_t n = count; n > 0; ) { + std::pair, IndexedNetlistModel::Status> cp = mp_indexer->child_circuit_from_index (circuits, n - 1); + QModelIndex child_index = createIndex (int (n - 1), 0, reinterpret_cast (size_t (index.internalPointer ()) + nprod * n)); + build_circuits_to_index (child_nprod, cp.first, model, child_index, map); + --n; + } +} + +QModelIndex +NetlistBrowserTreeModel::index_from_circuits (const std::pair &circuits) const +{ + if (m_circuits_to_index.empty ()) { + + size_t count = mp_indexer->top_circuit_count (); + for (size_t n = count; n > 0; ) { + std::pair, IndexedNetlistModel::Status> cp = mp_indexer->top_circuit_from_index (n - 1); + build_circuits_to_index (count + 1, cp.first, mp_indexer.get (), createIndex (int (n - 1), 0, reinterpret_cast (n)), m_circuits_to_index); + --n; + } + + } + + std::map, QModelIndex>::const_iterator m = m_circuits_to_index.find (circuits); + if (m != m_circuits_to_index.end ()) { + return m->second; + } else { + return QModelIndex (); + } +} + + db::NetlistCrossReference::Status NetlistBrowserTreeModel::status (const QModelIndex &index) const { - size_t nprod = 0, nlast = 0; - return cp_status_from_index (index, nprod, nlast).second; + size_t nprod = 0, nlast = 0, nnlast = 0; + return cp_status_from_index (index, nprod, nlast, nnlast).second; } Qt::ItemFlags @@ -276,8 +321,8 @@ NetlistBrowserTreeModel::index (int row, int column, const QModelIndex &parent) } else { - size_t nprod = 0, nlast = 0; - cp_status_from_index (parent, nprod, nlast); + size_t nprod = 0, nlast = 0, nnlast = 0; + cp_status_from_index (parent, nprod, nlast, nnlast); void *id = parent.internalPointer (); return createIndex (row, column, reinterpret_cast (reinterpret_cast (id) + size_t (row + 1) * nprod)); @@ -290,8 +335,8 @@ NetlistBrowserTreeModel::parent (const QModelIndex &index) const { if (index.isValid ()) { - size_t nprod = 0, nlast = 0; - cp_status_from_index (index, nprod, nlast); + size_t nprod = 0, nlast = 0, nnlast = 0; + cp_status_from_index (index, nprod, nlast, nnlast); tl_assert (nlast != 0); @@ -302,7 +347,11 @@ NetlistBrowserTreeModel::parent (const QModelIndex &index) const void *id = index.internalPointer (); size_t ids = reinterpret_cast (id); tl_assert (ids >= nprod); - return createIndex (int (ids / nprod - 1), index.column (), reinterpret_cast (ids % nprod)); + ids %= nprod; + + nprod /= nnlast; + + return createIndex (int (ids / nprod - 1), index.column (), reinterpret_cast (ids)); } diff --git a/src/laybasic/laybasic/layNetlistBrowserTreeModel.h b/src/laybasic/laybasic/layNetlistBrowserTreeModel.h index e3a12b21b..3dbf17e5f 100644 --- a/src/laybasic/laybasic/layNetlistBrowserTreeModel.h +++ b/src/laybasic/laybasic/layNetlistBrowserTreeModel.h @@ -76,6 +76,7 @@ public: } std::pair circuits_from_index (const QModelIndex &index) const; + QModelIndex index_from_circuits (const std::pair &circuits) const; private: NetlistBrowserTreeModel (const NetlistBrowserTreeModel &); @@ -84,11 +85,13 @@ private: QString text (const QModelIndex &index) const; QString search_text (const QModelIndex &index) const; db::NetlistCrossReference::Status status (const QModelIndex &index) const; - std::pair, db::NetlistCrossReference::Status> cp_status_from_index (const QModelIndex &index, size_t &nprod, size_t &nlast) const; + std::pair, db::NetlistCrossReference::Status> cp_status_from_index (const QModelIndex &index, size_t &nprod, size_t &nlast, size_t &nnlast) const; + void build_circuits_to_index (size_t nprod, const std::pair &circuits, IndexedNetlistModel *model, const QModelIndex &index, std::map, QModelIndex> &map) const; db::LayoutToNetlist *mp_l2ndb; db::LayoutVsSchematic *mp_lvsdb; std::auto_ptr mp_indexer; + mutable std::map, QModelIndex> m_circuits_to_index; int m_object_column; int m_status_column; }; diff --git a/src/laybasic/laybasic/layNetlistCrossReferenceModel.cc b/src/laybasic/laybasic/layNetlistCrossReferenceModel.cc index d28eb029e..3ac23075b 100644 --- a/src/laybasic/laybasic/layNetlistCrossReferenceModel.cc +++ b/src/laybasic/laybasic/layNetlistCrossReferenceModel.cc @@ -299,6 +299,11 @@ const db::Net *NetlistCrossReferenceModel::second_net_for (const db::Net *first) return mp_cross_ref->other_net_for (first); } +const db::Circuit *NetlistCrossReferenceModel::second_circuit_for (const db::Circuit *first) const +{ + return mp_cross_ref->other_circuit_for (first); +} + IndexedNetlistModel::net_subcircuit_pin_pair NetlistCrossReferenceModel::net_subcircuit_pinref_from_index (const net_pair &nets, size_t index) const { const db::NetlistCrossReference::PerNetData *data = mp_cross_ref->per_net_data_for (nets); diff --git a/src/laybasic/laybasic/layNetlistCrossReferenceModel.h b/src/laybasic/laybasic/layNetlistCrossReferenceModel.h index f51a8530d..7d3161ad1 100644 --- a/src/laybasic/laybasic/layNetlistCrossReferenceModel.h +++ b/src/laybasic/laybasic/layNetlistCrossReferenceModel.h @@ -63,6 +63,7 @@ public: virtual std::pair child_circuit_from_index (const circuit_pair &circuits, size_t index) const; virtual std::pair net_from_index (const circuit_pair &circuits, size_t index) const; virtual const db::Net *second_net_for (const db::Net *first) const; + virtual const db::Circuit *second_circuit_for (const db::Circuit *first) const; virtual net_subcircuit_pin_pair net_subcircuit_pinref_from_index (const net_pair &nets, size_t index) const; virtual net_terminal_pair net_terminalref_from_index (const net_pair &nets, size_t index) const; virtual net_pin_pair net_pinref_from_index (const net_pair &nets, size_t index) const;