mirror of https://github.com/KLayout/klayout.git
Functional netlist hierarchy tree.
This commit is contained in:
parent
577edea08b
commit
7c220c63e1
|
|
@ -41,6 +41,42 @@ namespace db
|
|||
|
||||
class Netlist;
|
||||
|
||||
/**
|
||||
* @brief An iterator wrapper for the child and parent circuit iterator
|
||||
*/
|
||||
template <class Iter, class Value>
|
||||
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<SubCircuit>::const_iterator const_refs_iterator;
|
||||
typedef tl::weak_collection<SubCircuit>::iterator refs_iterator;
|
||||
typedef tl::vector<Circuit *>::const_iterator child_circuit_iterator;
|
||||
typedef tl::vector<const Circuit *>::const_iterator const_child_circuit_iterator;
|
||||
typedef tl::vector<Circuit *>::const_iterator parent_circuit_iterator;
|
||||
typedef tl::vector<const Circuit *>::const_iterator const_parent_circuit_iterator;
|
||||
typedef dereferencing_iterator<tl::vector<Circuit *>::const_iterator, Circuit> child_circuit_iterator;
|
||||
typedef dereferencing_iterator<tl::vector<const Circuit *>::const_iterator, const Circuit> const_child_circuit_iterator;
|
||||
typedef dereferencing_iterator<tl::vector<Circuit *>::const_iterator, Circuit> parent_circuit_iterator;
|
||||
typedef dereferencing_iterator<tl::vector<const Circuit *>::const_iterator, const Circuit> const_parent_circuit_iterator;
|
||||
|
||||
/**
|
||||
* @brief Constructor
|
||||
|
|
|
|||
|
|
@ -184,7 +184,7 @@ void std_writer_impl<Keys>::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;
|
||||
|
|
|
|||
|
|
@ -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 ()) {
|
||||
|
|
|
|||
|
|
@ -55,10 +55,10 @@ public:
|
|||
typedef tl::shared_collection<DeviceAbstract> device_abstract_list;
|
||||
typedef device_abstract_list::const_iterator const_abstract_model_iterator;
|
||||
typedef device_abstract_list::iterator device_abstract_iterator;
|
||||
typedef tl::vector<Circuit *>::const_iterator top_down_circuit_iterator;
|
||||
typedef tl::vector<const Circuit *>::const_iterator const_top_down_circuit_iterator;
|
||||
typedef tl::vector<Circuit *>::const_reverse_iterator bottom_up_circuit_iterator;
|
||||
typedef tl::vector<const Circuit *>::const_reverse_iterator const_bottom_up_circuit_iterator;
|
||||
typedef dereferencing_iterator<tl::vector<Circuit *>::iterator, Circuit> top_down_circuit_iterator;
|
||||
typedef dereferencing_iterator<tl::vector<const Circuit *>::const_iterator, const Circuit> const_top_down_circuit_iterator;
|
||||
typedef dereferencing_iterator<tl::vector<Circuit *>::reverse_iterator, Circuit> bottom_up_circuit_iterator;
|
||||
typedef dereferencing_iterator<tl::vector<const Circuit *>::const_reverse_iterator, const Circuit> const_bottom_up_circuit_iterator;
|
||||
|
||||
/**
|
||||
* @brief Constructor
|
||||
|
|
|
|||
|
|
@ -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<size_t, std::pair<const db::Circuit *, const db::Circuit *> >::const_iterator i = cat2circuits.find (ccat);
|
||||
tl_assert (i != cat2circuits.end ());
|
||||
|
|
|
|||
|
|
@ -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 ();
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -204,49 +204,95 @@
|
|||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTreeView" name="directory_tree">
|
||||
<widget class="QFrame" name="frame_2">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
<verstretch>1</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="baseSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>4</height>
|
||||
</size>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<property name="contextMenuPolicy">
|
||||
<enum>Qt::ActionsContextMenu</enum>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Raised</enum>
|
||||
</property>
|
||||
<property name="selectionMode">
|
||||
<enum>QAbstractItemView::ExtendedSelection</enum>
|
||||
</property>
|
||||
<property name="selectionBehavior">
|
||||
<enum>QAbstractItemView::SelectRows</enum>
|
||||
</property>
|
||||
<property name="uniformRowHeights">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="sortingEnabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="allColumnsShowFocus">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<attribute name="headerVisible">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
<attribute name="headerCascadingSectionResizes">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
<attribute name="headerShowSortIndicator" stdset="0">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
<attribute name="headerStretchLastSection">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QSplitter" name="splitter">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<widget class="QTreeView" name="hierarchy_tree">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<attribute name="headerDefaultSectionSize">
|
||||
<number>100</number>
|
||||
</attribute>
|
||||
</widget>
|
||||
<widget class="QTreeView" name="directory_tree">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>1</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="baseSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="contextMenuPolicy">
|
||||
<enum>Qt::ActionsContextMenu</enum>
|
||||
</property>
|
||||
<property name="selectionMode">
|
||||
<enum>QAbstractItemView::ExtendedSelection</enum>
|
||||
</property>
|
||||
<property name="selectionBehavior">
|
||||
<enum>QAbstractItemView::SelectRows</enum>
|
||||
</property>
|
||||
<property name="uniformRowHeights">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="sortingEnabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="allColumnsShowFocus">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<attribute name="headerVisible">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
<attribute name="headerCascadingSectionResizes">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
<attribute name="headerShowSortIndicator" stdset="0">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
<attribute name="headerStretchLastSection">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
|
|
@ -338,6 +384,12 @@
|
|||
</customwidget>
|
||||
</customwidgets>
|
||||
<tabstops>
|
||||
<tabstop>backward</tabstop>
|
||||
<tabstop>forward</tabstop>
|
||||
<tabstop>info_button</tabstop>
|
||||
<tabstop>find_text</tabstop>
|
||||
<tabstop>find_button</tabstop>
|
||||
<tabstop>hierarchy_tree</tabstop>
|
||||
<tabstop>directory_tree</tabstop>
|
||||
</tabstops>
|
||||
<resources>
|
||||
|
|
|
|||
|
|
@ -272,15 +272,15 @@ SingleIndexedNetlistModel::parent_of (const subcircuit_pair &subcircuits) const
|
|||
std::pair<IndexedNetlistModel::circuit_pair, IndexedNetlistModel::Status>
|
||||
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::Circuit> ()), db::NetlistCrossReference::None);
|
||||
}
|
||||
|
||||
std::pair<IndexedNetlistModel::circuit_pair, IndexedNetlistModel::Status>
|
||||
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::Circuit> ()), db::NetlistCrossReference::None);
|
||||
}
|
||||
|
||||
std::pair<IndexedNetlistModel::circuit_pair, IndexedNetlistModel::Status>
|
||||
|
|
@ -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
|
||||
{
|
||||
|
|
|
|||
|
|
@ -90,6 +90,7 @@ public:
|
|||
virtual std::pair<circuit_pair, Status> circuit_from_index (size_t index) const = 0;
|
||||
virtual std::pair<net_pair, Status> 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_pair, Status> circuit_from_index (size_t index) const;
|
||||
virtual std::pair<circuit_pair, Status> child_circuit_from_index (const circuit_pair &circuits, size_t index) const;
|
||||
virtual std::pair<net_pair, Status> 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<netlist_pair, std::vector<circuit_pair> > m_circuit_by_index;
|
||||
mutable std::map<circuit_pair, std::vector<circuit_pair> > m_child_circuit_by_circuit_and_index;
|
||||
mutable std::map<circuit_pair, std::vector<net_pair> > m_net_by_circuit_and_index;
|
||||
mutable std::map<net_pair, std::vector<net_subcircuit_pin_pair> > m_subcircuit_pinref_by_net_and_index;
|
||||
mutable std::map<net_pair, std::vector<net_terminal_pair> > m_terminalref_by_net_and_index;
|
||||
|
|
|
|||
|
|
@ -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<const db::Circuit *, const db::Circuit *> &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<const db::Circuit *, const db::Circuit *>
|
||||
NetlistBrowserModel::circuit_from_index (const QModelIndex &index) const
|
||||
{
|
||||
return circuits_from_id (index.internalPointer ());
|
||||
}
|
||||
|
||||
std::pair<const db::Net *, const db::Net *>
|
||||
NetlistBrowserModel::net_from_index (const QModelIndex &index) const
|
||||
{
|
||||
|
|
|
|||
|
|
@ -135,6 +135,9 @@ public:
|
|||
std::pair<const db::Net *, const db::Net *> net_from_index (const QModelIndex &index) const;
|
||||
QModelIndex index_from_net (const std::pair<const db::Net *, const db::Net *> &net) const;
|
||||
QModelIndex index_from_net (const db::Net *net) const;
|
||||
std::pair<const db::Circuit *, const db::Circuit *> circuit_from_index (const QModelIndex &index) const;
|
||||
QModelIndex index_from_circuit (const std::pair<const db::Circuit *, const db::Circuit *> &circuit) const;
|
||||
QModelIndex index_from_circuit (const db::Circuit *circuit) const;
|
||||
|
||||
std::pair<const db::SubCircuit *, const db::SubCircuit *> subcircuit_from_index (const QModelIndex &index) const;
|
||||
|
||||
|
|
|
|||
|
|
@ -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<NetlistBrowserTreeModel *> (hierarchy_tree->model ());
|
||||
NetlistBrowserModel *netlist_model = dynamic_cast<NetlistBrowserModel *> (directory_tree->model ());
|
||||
if (! tree_model || ! netlist_model) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::pair<const db::Circuit *, const db::Circuit *> 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<NetlistBrowserTreeModel *> (hierarchy_tree->model ());
|
||||
NetlistBrowserModel *netlist_model = dynamic_cast<NetlistBrowserModel *> (directory_tree->model ());
|
||||
if (! tree_model || ! netlist_model) {
|
||||
return;
|
||||
}
|
||||
|
||||
void *id = index.internalPointer ();
|
||||
add_to_history (id, true);
|
||||
|
||||
std::pair<const db::Circuit *, const db::Circuit *> 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<NetlistBrowserModel *> (directory_tree->model ());
|
||||
if (! model) {
|
||||
NetlistBrowserTreeModel *tree_model = dynamic_cast<NetlistBrowserTreeModel *> (hierarchy_tree->model ());
|
||||
NetlistBrowserModel *netlist_model = dynamic_cast<NetlistBrowserModel *> (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<const db::Circuit *, const db::Circuit *> 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 ());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 ();
|
||||
|
|
|
|||
|
|
@ -202,7 +202,7 @@ NetlistBrowserTreeModel::search_text (const QModelIndex &index) const
|
|||
}
|
||||
|
||||
std::pair<std::pair<const db::Circuit *, const db::Circuit *>, 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<std::pair<const db::Circuit *, const db::Circuit *>, 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<const db::Circuit *, const db::Circuit *>
|
||||
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<const db::Circuit *, const db::Circuit *> &circuits, IndexedNetlistModel *model, const QModelIndex &index, std::map<std::pair<const db::Circuit *, const db::Circuit *>, 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<std::pair<const db::Circuit *, const db::Circuit *>, IndexedNetlistModel::Status> cp = mp_indexer->child_circuit_from_index (circuits, n - 1);
|
||||
QModelIndex child_index = createIndex (int (n - 1), 0, reinterpret_cast<void *> (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<const db::Circuit *, const db::Circuit *> &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<std::pair<const db::Circuit *, const db::Circuit *>, 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<void *> (n)), m_circuits_to_index);
|
||||
--n;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
std::map<std::pair<const db::Circuit *, const db::Circuit *>, 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<void *> (reinterpret_cast<size_t> (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<size_t> (id);
|
||||
tl_assert (ids >= nprod);
|
||||
return createIndex (int (ids / nprod - 1), index.column (), reinterpret_cast<void *> (ids % nprod));
|
||||
ids %= nprod;
|
||||
|
||||
nprod /= nnlast;
|
||||
|
||||
return createIndex (int (ids / nprod - 1), index.column (), reinterpret_cast<void *> (ids));
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -76,6 +76,7 @@ public:
|
|||
}
|
||||
|
||||
std::pair<const db::Circuit *, const db::Circuit *> circuits_from_index (const QModelIndex &index) const;
|
||||
QModelIndex index_from_circuits (const std::pair<const db::Circuit *, const db::Circuit *> &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<std::pair<const db::Circuit *, const db::Circuit *>, db::NetlistCrossReference::Status> cp_status_from_index (const QModelIndex &index, size_t &nprod, size_t &nlast) const;
|
||||
std::pair<std::pair<const db::Circuit *, const db::Circuit *>, 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<const db::Circuit *, const db::Circuit *> &circuits, IndexedNetlistModel *model, const QModelIndex &index, std::map<std::pair<const db::Circuit *, const db::Circuit *>, QModelIndex> &map) const;
|
||||
|
||||
db::LayoutToNetlist *mp_l2ndb;
|
||||
db::LayoutVsSchematic *mp_lvsdb;
|
||||
std::auto_ptr<IndexedNetlistModel> mp_indexer;
|
||||
mutable std::map<std::pair<const db::Circuit *, const db::Circuit *>, QModelIndex> m_circuits_to_index;
|
||||
int m_object_column;
|
||||
int m_status_column;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -63,6 +63,7 @@ public:
|
|||
virtual std::pair<circuit_pair, Status> child_circuit_from_index (const circuit_pair &circuits, size_t index) const;
|
||||
virtual std::pair<net_pair, Status> 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;
|
||||
|
|
|
|||
Loading…
Reference in New Issue