mirror of https://github.com/KLayout/klayout.git
WIP: netlist browser tree, highlights etc.
This commit is contained in:
parent
62ed7b9def
commit
f00f5c76b8
|
|
@ -426,20 +426,6 @@ IndexedNetlistModel::pin_pair pins_from_netrefs (const IndexedNetlistModel::net_
|
|||
return std::make_pair (pin1, pin2);
|
||||
}
|
||||
|
||||
static
|
||||
IndexedNetlistModel::net_pair nets_from_subcircuit_pins (const IndexedNetlistModel::subcircuit_pair &subcircuits, const IndexedNetlistModel::pin_pair &pins)
|
||||
{
|
||||
const db::Net *net1 = 0, *net2 = 0;
|
||||
if (pins.first && subcircuits.first) {
|
||||
net1 = subcircuits.first->net_for_pin (pins.first->id ());
|
||||
}
|
||||
if (pins.second && subcircuits.second) {
|
||||
net2 = subcircuits.second->net_for_pin (pins.second->id ());
|
||||
}
|
||||
|
||||
return std::make_pair (net1, net2);
|
||||
}
|
||||
|
||||
static
|
||||
IndexedNetlistModel::net_pair nets_from_circuit_pins (const IndexedNetlistModel::circuit_pair &circuits, const IndexedNetlistModel::pin_pair &pins)
|
||||
{
|
||||
|
|
@ -545,15 +531,6 @@ static size_t rows_for (const db::Device *device)
|
|||
}
|
||||
}
|
||||
|
||||
static size_t rows_for (const db::SubCircuit *subcircuit)
|
||||
{
|
||||
if (! subcircuit || ! subcircuit->circuit_ref ()) {
|
||||
return 0;
|
||||
} else {
|
||||
return subcircuit->circuit_ref ()->pin_count ();
|
||||
}
|
||||
}
|
||||
|
||||
static size_t rows_for (const db::NetTerminalRef *ref)
|
||||
{
|
||||
if (! ref || ! ref->device_class ()) {
|
||||
|
|
@ -851,7 +828,7 @@ class CircuitItemData
|
|||
: public NetlistModelItemData
|
||||
{
|
||||
public:
|
||||
CircuitItemData (NetlistModelItemData *parent, const IndexedNetlistModel::circuit_pair &cp);
|
||||
CircuitItemData (NetlistModelItemData *parent, const IndexedNetlistModel::circuit_pair &cp, const IndexedNetlistModel::subcircuit_pair &sp = IndexedNetlistModel::subcircuit_pair (0, 0));
|
||||
|
||||
virtual void do_ensure_children (NetlistBrowserModel *model);
|
||||
virtual QIcon icon (NetlistBrowserModel *model);
|
||||
|
|
@ -860,17 +837,23 @@ public:
|
|||
virtual std::string tooltip (NetlistBrowserModel *model);
|
||||
virtual db::NetlistCrossReference::Status status (NetlistBrowserModel *model);
|
||||
|
||||
virtual std::pair<const db::Circuit *, const db::Circuit *> circuits ()
|
||||
virtual std::pair<const db::Circuit *, const db::Circuit *> circuits_of_this ()
|
||||
{
|
||||
return m_cp;
|
||||
}
|
||||
|
||||
virtual std::pair<const db::SubCircuit *, const db::SubCircuit *> subcircuits_of_this ()
|
||||
{
|
||||
return m_sp;
|
||||
}
|
||||
|
||||
CircuitNetItemData *circuit_net_item (NetlistBrowserModel *model, const IndexedNetlistModel::net_pair &np);
|
||||
CircuitDeviceItemData *circuit_device_item (NetlistBrowserModel *model, const IndexedNetlistModel::device_pair &dp);
|
||||
CircuitSubCircuitItemData *circuit_subcircuit_item (NetlistBrowserModel *model, const IndexedNetlistModel::subcircuit_pair &sp);
|
||||
|
||||
private:
|
||||
IndexedNetlistModel::circuit_pair m_cp;
|
||||
IndexedNetlistModel::subcircuit_pair m_sp;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------
|
||||
|
|
@ -918,13 +901,14 @@ public:
|
|||
return m_pp;
|
||||
}
|
||||
|
||||
virtual std::pair<const db::Pin *, const db::Pin *> pins ()
|
||||
virtual std::pair<const db::Pin *, const db::Pin *> pins_of_this ()
|
||||
{
|
||||
return pp ();
|
||||
}
|
||||
|
||||
private:
|
||||
IndexedNetlistModel::pin_pair m_pp;
|
||||
bool m_pin_seen;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------
|
||||
|
|
@ -1017,13 +1001,14 @@ public:
|
|||
return m_tp;
|
||||
}
|
||||
|
||||
virtual std::pair<const db::Device *, const db::Device *> devices ()
|
||||
virtual std::pair<const db::Device *, const db::Device *> devices_of_this ()
|
||||
{
|
||||
return dp ();
|
||||
}
|
||||
|
||||
private:
|
||||
IndexedNetlistModel::net_terminal_pair m_tp;
|
||||
bool m_device_seen;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------
|
||||
|
|
@ -1047,11 +1032,6 @@ public:
|
|||
return p->dp ();
|
||||
}
|
||||
|
||||
virtual std::pair<const db::Net *, const db::Net *> nets_of_this ()
|
||||
{
|
||||
return m_np;
|
||||
}
|
||||
|
||||
private:
|
||||
std::pair<const db::DeviceTerminalDefinition *, const db::DeviceTerminalDefinition *> m_tp;
|
||||
IndexedNetlistModel::net_pair m_np;
|
||||
|
|
@ -1089,12 +1069,12 @@ public:
|
|||
return pins_from_pinrefs (m_sp);
|
||||
}
|
||||
|
||||
virtual std::pair<const db::SubCircuit *, const db::SubCircuit *> subcircuits ()
|
||||
virtual std::pair<const db::SubCircuit *, const db::SubCircuit *> subcircuits_of_this ()
|
||||
{
|
||||
return subcircuits_from_pinrefs (m_sp);
|
||||
}
|
||||
|
||||
virtual std::pair<const db::Pin *, const db::Pin *> pins ()
|
||||
virtual std::pair<const db::Pin *, const db::Pin *> pins_of_this ()
|
||||
{
|
||||
return m_pp;
|
||||
}
|
||||
|
|
@ -1102,6 +1082,7 @@ public:
|
|||
private:
|
||||
IndexedNetlistModel::net_subcircuit_pin_pair m_sp;
|
||||
IndexedNetlistModel::pin_pair m_pp;
|
||||
bool m_subcircuit_seen;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------
|
||||
|
|
@ -1124,9 +1105,9 @@ public:
|
|||
return m_pp;
|
||||
}
|
||||
|
||||
virtual std::pair<const db::Pin *, const db::Pin *> pins ()
|
||||
virtual std::pair<const db::Pin *, const db::Pin *> pins_of_this ()
|
||||
{
|
||||
return std::pair<const db::Pin *, const db::Pin *> (pins_from_netrefs (m_pp));
|
||||
return pins_from_pinrefs (m_pp);
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
@ -1149,7 +1130,7 @@ public:
|
|||
virtual std::string tooltip (NetlistBrowserModel *model);
|
||||
virtual db::NetlistCrossReference::Status status (NetlistBrowserModel *model);
|
||||
|
||||
virtual std::pair<const db::Pin *, const db::Pin *> pins ()
|
||||
virtual std::pair<const db::Pin *, const db::Pin *> pins_of_this ()
|
||||
{
|
||||
return pins_from_pinrefs (m_pp);
|
||||
}
|
||||
|
|
@ -1178,13 +1159,14 @@ public:
|
|||
return m_sp;
|
||||
}
|
||||
|
||||
virtual std::pair<const db::SubCircuit *, const db::SubCircuit *> subcircuits ()
|
||||
CircuitItemData *circuit_item ()
|
||||
{
|
||||
return m_sp;
|
||||
return mp_circuit_node;
|
||||
}
|
||||
|
||||
private:
|
||||
IndexedNetlistModel::subcircuit_pair m_sp;
|
||||
CircuitItemData *mp_circuit_node;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------
|
||||
|
|
@ -1207,7 +1189,7 @@ public:
|
|||
return subcircuits_from_pinrefs (m_pp);
|
||||
}
|
||||
|
||||
virtual std::pair<const db::Pin *, const db::Pin *> pins ()
|
||||
virtual std::pair<const db::Pin *, const db::Pin *> pins_of_this ()
|
||||
{
|
||||
return pins_from_netrefs (m_pp);
|
||||
}
|
||||
|
|
@ -1236,7 +1218,7 @@ public:
|
|||
return m_dp;
|
||||
}
|
||||
|
||||
virtual std::pair<const db::Device *, const db::Device *> devices ()
|
||||
virtual std::pair<const db::Device *, const db::Device *> devices_of_this ()
|
||||
{
|
||||
return m_dp;
|
||||
}
|
||||
|
|
@ -1323,28 +1305,120 @@ NetlistModelItemData::child (size_t n)
|
|||
return (n < m_children_per_index.size () ? m_children_per_index [n] : 0);
|
||||
}
|
||||
|
||||
std::pair<const db::Circuit *, const db::Circuit *>
|
||||
NetlistModelItemData::circuits_of_this ()
|
||||
{
|
||||
return std::pair<const db::Circuit *, const db::Circuit *> (0, 0);
|
||||
}
|
||||
|
||||
std::pair<const db::Circuit *, const db::Circuit *>
|
||||
NetlistModelItemData::circuits ()
|
||||
{
|
||||
return mp_parent ? mp_parent->circuits () : std::pair<const db::Circuit *, const db::Circuit *> (0, 0);
|
||||
std::pair<const db::Circuit *, const db::Circuit *> r = circuits_of_this ();
|
||||
if (! mp_parent || r.first || r.second) {
|
||||
return r;
|
||||
} else {
|
||||
return mp_parent->circuits ();
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
NetlistModelItemData::derived_from_circuits (const std::pair<const db::Circuit *, const db::Circuit *> &sp)
|
||||
{
|
||||
if (circuits_of_this () == sp) {
|
||||
return true;
|
||||
} else if (mp_parent) {
|
||||
return mp_parent->derived_from_circuits (sp);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
std::pair<const db::Device *, const db::Device *>
|
||||
NetlistModelItemData::devices_of_this ()
|
||||
{
|
||||
return std::pair<const db::Device *, const db::Device *> (0, 0);
|
||||
}
|
||||
|
||||
std::pair<const db::Device *, const db::Device *>
|
||||
NetlistModelItemData::devices ()
|
||||
{
|
||||
return mp_parent ? mp_parent->devices () : std::pair<const db::Device *, const db::Device *> (0, 0);
|
||||
std::pair<const db::Device *, const db::Device *> r = devices_of_this ();
|
||||
if (! mp_parent || r.first || r.second) {
|
||||
return r;
|
||||
} else {
|
||||
return mp_parent->devices ();
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
NetlistModelItemData::derived_from_devices (const std::pair<const db::Device *, const db::Device *> &sp)
|
||||
{
|
||||
if (devices_of_this () == sp) {
|
||||
return true;
|
||||
} else if (mp_parent) {
|
||||
return mp_parent->derived_from_devices (sp);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
std::pair<const db::Pin *, const db::Pin *>
|
||||
NetlistModelItemData::pins_of_this ()
|
||||
{
|
||||
return std::pair<const db::Pin *, const db::Pin *> (0, 0);
|
||||
}
|
||||
|
||||
std::pair<const db::Pin *, const db::Pin *>
|
||||
NetlistModelItemData::pins ()
|
||||
{
|
||||
return mp_parent ? mp_parent->pins () : std::pair<const db::Pin *, const db::Pin *> (0, 0);
|
||||
std::pair<const db::Pin *, const db::Pin *> r = pins_of_this ();
|
||||
if (! mp_parent || r.first || r.second) {
|
||||
return r;
|
||||
} else {
|
||||
return mp_parent->pins ();
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
NetlistModelItemData::derived_from_pins (const std::pair<const db::Pin *, const db::Pin *> &sp)
|
||||
{
|
||||
if (pins_of_this () == sp) {
|
||||
return true;
|
||||
} else if (mp_parent) {
|
||||
return mp_parent->derived_from_pins (sp);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
std::pair<const db::SubCircuit *, const db::SubCircuit *>
|
||||
NetlistModelItemData::subcircuits_of_this ()
|
||||
{
|
||||
return std::pair<const db::SubCircuit *, const db::SubCircuit *> (0, 0);
|
||||
}
|
||||
|
||||
std::pair<const db::SubCircuit *, const db::SubCircuit *>
|
||||
NetlistModelItemData::subcircuits ()
|
||||
{
|
||||
return mp_parent ? mp_parent->subcircuits () : std::pair<const db::SubCircuit *, const db::SubCircuit *> (0, 0);
|
||||
std::pair<const db::SubCircuit *, const db::SubCircuit *> r = subcircuits_of_this ();
|
||||
if (! mp_parent || r.first || r.second) {
|
||||
return r;
|
||||
} else {
|
||||
return mp_parent->subcircuits ();
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
NetlistModelItemData::derived_from_subcircuits (const std::pair<const db::SubCircuit *, const db::SubCircuit *> &sp)
|
||||
{
|
||||
if (subcircuits_of_this () == sp) {
|
||||
return true;
|
||||
} else if (mp_parent) {
|
||||
return mp_parent->derived_from_subcircuits (sp);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
std::pair<const db::Net *, const db::Net *>
|
||||
|
|
@ -1425,6 +1499,10 @@ RootItemData::status (NetlistBrowserModel * /*model*/)
|
|||
CircuitItemData *
|
||||
RootItemData::circuit_item (NetlistBrowserModel *model, const IndexedNetlistModel::circuit_pair &cp)
|
||||
{
|
||||
if (! cp.first && ! cp.second) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t index = model->indexer ()->circuit_index (cp);
|
||||
ensure_children (model);
|
||||
return dynamic_cast<CircuitItemData *> (child (index));
|
||||
|
|
@ -1432,8 +1510,8 @@ RootItemData::circuit_item (NetlistBrowserModel *model, const IndexedNetlistMode
|
|||
|
||||
// ----------------------------------------------------------------------------------
|
||||
|
||||
CircuitItemData::CircuitItemData (NetlistModelItemData *parent, const IndexedNetlistModel::circuit_pair &cp)
|
||||
: NetlistModelItemData (parent), m_cp (cp)
|
||||
CircuitItemData::CircuitItemData (NetlistModelItemData *parent, const IndexedNetlistModel::circuit_pair &cp, const IndexedNetlistModel::subcircuit_pair &sp)
|
||||
: NetlistModelItemData (parent), m_cp (cp), m_sp (sp)
|
||||
{ }
|
||||
|
||||
void
|
||||
|
|
@ -1497,6 +1575,8 @@ CircuitItemData::status (NetlistBrowserModel *model)
|
|||
CircuitNetItemData *
|
||||
CircuitItemData::circuit_net_item (NetlistBrowserModel *model, const IndexedNetlistModel::net_pair &np)
|
||||
{
|
||||
ensure_children (model);
|
||||
|
||||
for (size_t i = 0; i < child_count (); ++i) {
|
||||
CircuitNetItemData *d = static_cast<CircuitItemNodeData *> (child (i))->circuit_net_item (model, np);
|
||||
if (d) {
|
||||
|
|
@ -1509,6 +1589,8 @@ CircuitItemData::circuit_net_item (NetlistBrowserModel *model, const IndexedNetl
|
|||
CircuitDeviceItemData *
|
||||
CircuitItemData::circuit_device_item (NetlistBrowserModel *model, const IndexedNetlistModel::device_pair &dp)
|
||||
{
|
||||
ensure_children (model);
|
||||
|
||||
for (size_t i = 0; i < child_count (); ++i) {
|
||||
CircuitDeviceItemData *d = static_cast<CircuitItemNodeData *> (child (i))->circuit_device_item (model, dp);
|
||||
if (d) {
|
||||
|
|
@ -1521,6 +1603,8 @@ CircuitItemData::circuit_device_item (NetlistBrowserModel *model, const IndexedN
|
|||
CircuitSubCircuitItemData *
|
||||
CircuitItemData::circuit_subcircuit_item (NetlistBrowserModel *model, const IndexedNetlistModel::subcircuit_pair &sp)
|
||||
{
|
||||
ensure_children (model);
|
||||
|
||||
for (size_t i = 0; i < child_count (); ++i) {
|
||||
CircuitSubCircuitItemData *d = static_cast<CircuitItemNodeData *> (child (i))->circuit_subcircuit_item (model, sp);
|
||||
if (d) {
|
||||
|
|
@ -1626,6 +1710,12 @@ CircuitItemNodeData::status (NetlistBrowserModel * /*model*/)
|
|||
CircuitNetItemData *
|
||||
CircuitItemNodeData::circuit_net_item (NetlistBrowserModel *model, const IndexedNetlistModel::net_pair &np)
|
||||
{
|
||||
if (! np.first && ! np.second) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ensure_children (model);
|
||||
|
||||
if (m_type == Nets) {
|
||||
ensure_children (model);
|
||||
size_t index = model->indexer ()->net_index (np);
|
||||
|
|
@ -1638,6 +1728,12 @@ CircuitItemNodeData::circuit_net_item (NetlistBrowserModel *model, const Indexed
|
|||
CircuitDeviceItemData *
|
||||
CircuitItemNodeData::circuit_device_item (NetlistBrowserModel *model, const IndexedNetlistModel::device_pair &dp)
|
||||
{
|
||||
if (! dp.first && ! dp.second) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ensure_children (model);
|
||||
|
||||
if (m_type == Devices) {
|
||||
ensure_children (model);
|
||||
size_t index = model->indexer ()->device_index (dp);
|
||||
|
|
@ -1650,6 +1746,12 @@ CircuitItemNodeData::circuit_device_item (NetlistBrowserModel *model, const Inde
|
|||
CircuitSubCircuitItemData *
|
||||
CircuitItemNodeData::circuit_subcircuit_item (NetlistBrowserModel *model, const IndexedNetlistModel::subcircuit_pair &sp)
|
||||
{
|
||||
if (! sp.first && ! sp.second) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ensure_children (model);
|
||||
|
||||
if (m_type == SubCircuits) {
|
||||
ensure_children (model);
|
||||
size_t index = model->indexer ()->subcircuit_index (sp);
|
||||
|
|
@ -1662,13 +1764,16 @@ CircuitItemNodeData::circuit_subcircuit_item (NetlistBrowserModel *model, const
|
|||
// ----------------------------------------------------------------------------------
|
||||
|
||||
CircuitPinItemData::CircuitPinItemData (NetlistModelItemData *parent, const IndexedNetlistModel::pin_pair &pp)
|
||||
: NetlistModelItemData (parent), m_pp (pp)
|
||||
{ }
|
||||
: NetlistModelItemData (parent), m_pp (pp), m_pin_seen (parent && parent->derived_from_pins (pp))
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
CircuitPinItemData::do_ensure_children (NetlistBrowserModel * /*model*/)
|
||||
{
|
||||
push_back (new CircuitPinNetItemData (this, nets_from_circuit_pins (circuits (), pp ())));
|
||||
if (! m_pin_seen) {
|
||||
push_back (new CircuitNetItemData (this, nets_from_circuit_pins (circuits (), pp ())));
|
||||
}
|
||||
}
|
||||
|
||||
QIcon
|
||||
|
|
@ -1684,7 +1789,11 @@ CircuitPinItemData::text (int column, NetlistBrowserModel *model)
|
|||
// + single mode: xname | <empty> | <empty>
|
||||
// + dual mode: xname(a)/xname(b) | xname(a) | xname(b)
|
||||
if (column == model->object_column ()) {
|
||||
return escaped (str_from_expanded_names (pp (), model->indexer ()->is_single ()));
|
||||
std::string suffix;
|
||||
if (m_pin_seen) {
|
||||
suffix = tl::to_string (tr (" (already seen)"));
|
||||
}
|
||||
return escaped (str_from_expanded_names (pp (), model->indexer ()->is_single ()) + suffix);
|
||||
} else if (!model->indexer ()->is_single () && (column == model->first_column () || column == model->second_column ())) {
|
||||
return escaped (str_from_expanded_name (column == model->first_column () ? pp ().first : pp ().second));
|
||||
}
|
||||
|
|
@ -1714,6 +1823,7 @@ CircuitPinItemData::status (NetlistBrowserModel *model)
|
|||
|
||||
// ----------------------------------------------------------------------------------
|
||||
|
||||
// @@@ remove?
|
||||
CircuitPinNetItemData::CircuitPinNetItemData (NetlistModelItemData *parent, const IndexedNetlistModel::net_pair &np)
|
||||
: NetlistModelItemData (parent), m_np (np)
|
||||
{ }
|
||||
|
|
@ -1832,12 +1942,16 @@ CircuitNetItemData::status (NetlistBrowserModel *model)
|
|||
// ----------------------------------------------------------------------------------
|
||||
|
||||
CircuitNetDeviceTerminalItemData::CircuitNetDeviceTerminalItemData (NetlistModelItemData *parent, const IndexedNetlistModel::net_terminal_pair &tp)
|
||||
: NetlistModelItemData (parent), m_tp (tp)
|
||||
: NetlistModelItemData (parent), m_tp (tp), m_device_seen (parent && parent->derived_from_devices (dp ()))
|
||||
{ }
|
||||
|
||||
void
|
||||
CircuitNetDeviceTerminalItemData::do_ensure_children (NetlistBrowserModel *model)
|
||||
{
|
||||
if (m_device_seen) {
|
||||
return;
|
||||
}
|
||||
|
||||
size_t n = std::max (rows_for (m_tp.first), rows_for (m_tp.second));
|
||||
for (size_t i = 0; i < n; ++i) {
|
||||
std::pair<const db::DeviceClass *, const db::DeviceClass *> device_classes = device_classes_from_devices (dp ());
|
||||
|
|
@ -1862,10 +1976,15 @@ CircuitNetDeviceTerminalItemData::text (int column, NetlistBrowserModel *model)
|
|||
|
||||
std::pair<const db::DeviceTerminalDefinition *, const db::DeviceTerminalDefinition *> termdefs = terminal_defs_from_terminal_refs (m_tp);
|
||||
|
||||
std::string suffix;
|
||||
if (m_device_seen) {
|
||||
suffix = tl::to_string (tr (" (already seen)"));
|
||||
}
|
||||
|
||||
if (model->indexer ()->is_single ()) {
|
||||
return escaped (str_from_name (termdefs.first) + field_sep + device_string (dp ().first));
|
||||
return escaped (str_from_name (termdefs.first) + field_sep + device_string (dp ().first) + suffix);
|
||||
} else {
|
||||
return escaped (str_from_names (termdefs, model->indexer ()->is_single ()) + field_sep + devices_string (dp (), model->indexer ()->is_single (), true /*with parameters*/));
|
||||
return escaped (str_from_names (termdefs, model->indexer ()->is_single ()) + field_sep + devices_string (dp (), model->indexer ()->is_single (), true /*with parameters*/) + suffix);
|
||||
}
|
||||
|
||||
} else if (column == model->first_column () || column == model->second_column ()) {
|
||||
|
|
@ -1963,20 +2082,27 @@ CircuitNetDeviceTerminalOthersItemData::status (NetlistBrowserModel *model)
|
|||
// ----------------------------------------------------------------------------------
|
||||
|
||||
CircuitNetSubCircuitPinItemData::CircuitNetSubCircuitPinItemData (NetlistModelItemData *parent, const IndexedNetlistModel::net_subcircuit_pin_pair &sp)
|
||||
: NetlistModelItemData (parent), m_sp (sp)
|
||||
: NetlistModelItemData (parent), m_sp (sp), m_subcircuit_seen (parent && parent->derived_from_subcircuits (subcircuits ()))
|
||||
{ }
|
||||
|
||||
void
|
||||
CircuitNetSubCircuitPinItemData::do_ensure_children (NetlistBrowserModel *model)
|
||||
{
|
||||
IndexedNetlistModel::subcircuit_pair subcircuits = subcircuits_from_pinrefs (sp ());
|
||||
|
||||
size_t n = model->indexer ()->subcircuit_pin_count (subcircuits);
|
||||
for (size_t i = 0; i < n; ++i) {
|
||||
IndexedNetlistModel::net_subcircuit_pin_pair pp = model->indexer ()->subcircuit_pinref_from_index (subcircuits, i);
|
||||
bool is_seen = derived_from_nets (nets_from_pinrefs (pp));
|
||||
push_back (new CircuitNetSubCircuitPinOthersItemData (this, pp, is_seen));
|
||||
if (m_subcircuit_seen) {
|
||||
return;
|
||||
}
|
||||
|
||||
IndexedNetlistModel::subcircuit_pair subcircuits = subcircuits_from_pinrefs (sp ());
|
||||
IndexedNetlistModel::circuit_pair circuits = circuit_refs_from_subcircuits (subcircuits);
|
||||
IndexedNetlistModel::pin_pair pins = pins_from_pinrefs (m_sp);
|
||||
IndexedNetlistModel::net_pair nets = nets_from_circuit_pins (circuits, pins);
|
||||
|
||||
// Because of pin ambiguities the net identity might need to be fixed
|
||||
if (nets.first) {
|
||||
nets.second = model->indexer ()->second_net_for (nets.first);
|
||||
}
|
||||
|
||||
push_back (new CircuitNetItemData (this, nets));
|
||||
}
|
||||
|
||||
QIcon
|
||||
|
|
@ -1993,7 +2119,14 @@ CircuitNetSubCircuitPinItemData::text (int column, NetlistBrowserModel *model)
|
|||
IndexedNetlistModel::circuit_pair circuit_refs = circuit_refs_from_subcircuits (subcircuits);
|
||||
|
||||
if (column == model->object_column ()) {
|
||||
return model->make_link_to (pp (), circuit_refs) + tl::to_qstring (field_sep) + model->make_link_to (circuit_refs);
|
||||
|
||||
QString suffix;
|
||||
if (m_subcircuit_seen) {
|
||||
suffix = tr (" (already seen)");
|
||||
}
|
||||
|
||||
return model->make_link_to (pp (), circuit_refs) + tl::to_qstring (field_sep) + model->make_link_to (circuit_refs) + suffix;
|
||||
|
||||
} else if (column == model->first_column () || column == model->second_column ()) {
|
||||
return model->make_link_to (subcircuits, column);
|
||||
}
|
||||
|
|
@ -2147,7 +2280,7 @@ CircuitNetPinItemData::status (NetlistBrowserModel * /*model*/)
|
|||
// ----------------------------------------------------------------------------------
|
||||
|
||||
CircuitSubCircuitItemData::CircuitSubCircuitItemData (NetlistModelItemData *parent, const IndexedNetlistModel::subcircuit_pair &sp)
|
||||
: NetlistModelItemData (parent), m_sp (sp)
|
||||
: NetlistModelItemData (parent), m_sp (sp), mp_circuit_node (0)
|
||||
{ }
|
||||
|
||||
void
|
||||
|
|
@ -2158,12 +2291,16 @@ CircuitSubCircuitItemData::do_ensure_children (NetlistBrowserModel *model)
|
|||
IndexedNetlistModel::net_subcircuit_pin_pair pp = model->indexer ()->subcircuit_pinref_from_index (sp (), i);
|
||||
push_back (new CircuitSubCircuitPinItemData (this, pp));
|
||||
}
|
||||
|
||||
// plus one item for the circuit reference
|
||||
mp_circuit_node = new CircuitItemData (this, circuit_refs_from_subcircuits (m_sp), m_sp);
|
||||
push_back (mp_circuit_node);
|
||||
}
|
||||
|
||||
QIcon
|
||||
CircuitSubCircuitItemData::icon (NetlistBrowserModel * /*model*/)
|
||||
{
|
||||
return icon_for_circuit ();
|
||||
return icon_for_subcircuit ();
|
||||
}
|
||||
|
||||
QString
|
||||
|
|
@ -2493,8 +2630,71 @@ NetlistBrowserModel::data (const QModelIndex &index, int role) const
|
|||
return QVariant ();
|
||||
}
|
||||
|
||||
NetlistObjectPath
|
||||
NetlistBrowserModel::netpath_from_index (const QModelIndex &index) const
|
||||
{
|
||||
NetlistObjectPath np;
|
||||
np.net = net_from_index (index, false);
|
||||
np.device = device_from_index (index, false);
|
||||
|
||||
QModelIndex i = index;
|
||||
while (i.isValid ()) {
|
||||
|
||||
IndexedNetlistModel::subcircuit_pair sp = subcircuit_from_index (i, false);
|
||||
if (sp.first || sp.second) {
|
||||
np.path.push_front (sp);
|
||||
} else {
|
||||
IndexedNetlistModel::circuit_pair cp = circuit_from_index (i, false);
|
||||
if (cp.first || cp.second) {
|
||||
np.root = cp;
|
||||
}
|
||||
}
|
||||
|
||||
i = parent (i);
|
||||
|
||||
}
|
||||
|
||||
return np;
|
||||
}
|
||||
|
||||
QModelIndex
|
||||
NetlistBrowserModel::index_from_url (const QString &a)
|
||||
NetlistBrowserModel::index_from_netpath (const NetlistObjectPath &path)
|
||||
{
|
||||
QModelIndex index = index_from_circuit (path.root);
|
||||
|
||||
CircuitItemData *node = dynamic_cast<CircuitItemData *> ((NetlistModelItemData *) (index.internalPointer ()));
|
||||
|
||||
for (std::list<std::pair<const db::SubCircuit *, const db::SubCircuit *> >::const_iterator p = path.path.begin (); p != path.path.end () && node; ++p) {
|
||||
CircuitSubCircuitItemData *sc_node = node->circuit_subcircuit_item (this, *p);
|
||||
if (sc_node) {
|
||||
sc_node->ensure_children (this);
|
||||
node = sc_node->circuit_item ();
|
||||
} else {
|
||||
node = 0;
|
||||
}
|
||||
}
|
||||
|
||||
CircuitNetItemData *net_node = 0;
|
||||
CircuitDeviceItemData *device_node = 0;
|
||||
|
||||
if (node) {
|
||||
net_node = node->circuit_net_item (const_cast<NetlistBrowserModel *> (this), path.net);
|
||||
device_node = node->circuit_device_item (const_cast<NetlistBrowserModel *> (this), path.device);
|
||||
}
|
||||
|
||||
if (net_node) {
|
||||
return createIndex (int (net_node->index ()), 0, (void *) net_node);
|
||||
} else if (device_node) {
|
||||
return createIndex (int (device_node->index ()), 0, (void *) device_node);
|
||||
} else if (node) {
|
||||
return createIndex (int (node->index ()), 0, (void *) node);
|
||||
} else {
|
||||
return QModelIndex ();
|
||||
}
|
||||
}
|
||||
|
||||
QModelIndex
|
||||
NetlistBrowserModel::index_from_url (const QString &a) const
|
||||
{
|
||||
QUrl url (a);
|
||||
|
||||
|
|
@ -2633,12 +2833,12 @@ NetlistBrowserModel::make_link_to (const std::pair<const db::Circuit *, const db
|
|||
QString
|
||||
NetlistBrowserModel::make_link_to (const std::pair<const db::SubCircuit *, const db::SubCircuit *> &subcircuits, int column) const
|
||||
{
|
||||
QModelIndex idx;
|
||||
|
||||
if ((! subcircuits.first || column == m_second_column) && (! subcircuits.second || column == m_first_column)) {
|
||||
return QString ();
|
||||
} else {
|
||||
|
||||
QModelIndex idx = index_from_subcircuit (subcircuits);
|
||||
|
||||
if (mp_indexer->is_single () || column == m_first_column) {
|
||||
return build_url (idx, str_from_expanded_name (subcircuits.first));
|
||||
} else if (column == m_second_column) {
|
||||
|
|
@ -2862,6 +3062,21 @@ NetlistBrowserModel::index_from_circuit (const std::pair<const db::Circuit *, co
|
|||
return QModelIndex ();
|
||||
}
|
||||
|
||||
QModelIndex
|
||||
NetlistBrowserModel::index_from_subcircuit (const std::pair<const db::SubCircuit *, const db::SubCircuit *> &subcircuits) const
|
||||
{
|
||||
IndexedNetlistModel::circuit_pair circuits (subcircuits.first ? subcircuits.first->circuit () : 0, subcircuits.second ? subcircuits.second->circuit () : 0);
|
||||
CircuitItemData *ci = root ()->circuit_item (const_cast<NetlistBrowserModel *> (this), circuits);
|
||||
if (ci) {
|
||||
CircuitSubCircuitItemData *si = ci->circuit_subcircuit_item (const_cast<NetlistBrowserModel *> (this), subcircuits);
|
||||
if (si) {
|
||||
return createIndex (int (si->index ()), 0, (void *) si);
|
||||
}
|
||||
}
|
||||
|
||||
return QModelIndex ();
|
||||
}
|
||||
|
||||
QModelIndex
|
||||
NetlistBrowserModel::index_from_circuit (const db::Circuit *net) const
|
||||
{
|
||||
|
|
@ -2869,46 +3084,46 @@ NetlistBrowserModel::index_from_circuit (const db::Circuit *net) const
|
|||
}
|
||||
|
||||
std::pair<const db::Circuit *, const db::Circuit *>
|
||||
NetlistBrowserModel::circuit_from_index (const QModelIndex &index) const
|
||||
NetlistBrowserModel::circuit_from_index (const QModelIndex &index, bool include_parents) const
|
||||
{
|
||||
NetlistModelItemData *d = (NetlistModelItemData *) (index.internalPointer ());
|
||||
if (! d) {
|
||||
return std::pair<const db::Circuit *, const db::Circuit *> (0, 0);
|
||||
} else {
|
||||
return d->circuits ();
|
||||
return include_parents ? d->circuits () : d->circuits_of_this ();
|
||||
}
|
||||
}
|
||||
|
||||
std::pair<const db::Net *, const db::Net *>
|
||||
NetlistBrowserModel::net_from_index (const QModelIndex &index) const
|
||||
NetlistBrowserModel::net_from_index (const QModelIndex &index, bool include_parents) const
|
||||
{
|
||||
NetlistModelItemData *d = (NetlistModelItemData *) (index.internalPointer ());
|
||||
if (! d) {
|
||||
return std::pair<const db::Net *, const db::Net *> (0, 0);
|
||||
} else {
|
||||
return d->nets ();
|
||||
return include_parents ? d->nets () : d->nets_of_this ();
|
||||
}
|
||||
}
|
||||
|
||||
std::pair<const db::Device *, const db::Device *>
|
||||
NetlistBrowserModel::device_from_index (const QModelIndex &index) const
|
||||
NetlistBrowserModel::device_from_index (const QModelIndex &index, bool include_parents) const
|
||||
{
|
||||
NetlistModelItemData *d = (NetlistModelItemData *) (index.internalPointer ());
|
||||
if (! d) {
|
||||
return std::pair<const db::Device *, const db::Device *> (0, 0);
|
||||
} else {
|
||||
return d->devices ();
|
||||
return include_parents ? d->devices () : d->devices_of_this ();
|
||||
}
|
||||
}
|
||||
|
||||
std::pair<const db::SubCircuit *, const db::SubCircuit *>
|
||||
NetlistBrowserModel::subcircuit_from_index (const QModelIndex &index) const
|
||||
NetlistBrowserModel::subcircuit_from_index (const QModelIndex &index, bool include_parents) const
|
||||
{
|
||||
NetlistModelItemData *d = (NetlistModelItemData *) (index.internalPointer ());
|
||||
if (! d) {
|
||||
return std::pair<const db::SubCircuit *, const db::SubCircuit *> (0, 0);
|
||||
} else {
|
||||
return d->subcircuits ();
|
||||
return include_parents ? d->subcircuits () : d->subcircuits_of_this ();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -146,12 +146,23 @@ public:
|
|||
|
||||
NetlistModelItemData *child (size_t n);
|
||||
|
||||
virtual std::pair<const db::Circuit *, const db::Circuit *> circuits ();
|
||||
virtual std::pair<const db::Device *, const db::Device *> devices ();
|
||||
virtual std::pair<const db::Pin *, const db::Pin *> pins ();
|
||||
virtual std::pair<const db::SubCircuit *, const db::SubCircuit *> subcircuits ();
|
||||
virtual std::pair<const db::Net *, const db::Net *> nets_of_this ();
|
||||
virtual std::pair<const db::Circuit *, const db::Circuit *> circuits_of_this ();
|
||||
std::pair<const db::Circuit *, const db::Circuit *> circuits ();
|
||||
bool derived_from_circuits (const std::pair<const db::Circuit *, const db::Circuit *> &sp);
|
||||
|
||||
virtual std::pair<const db::Device *, const db::Device *> devices_of_this ();
|
||||
std::pair<const db::Device *, const db::Device *> devices ();
|
||||
bool derived_from_devices (const std::pair<const db::Device *, const db::Device *> &sp);
|
||||
|
||||
virtual std::pair<const db::Pin *, const db::Pin *> pins_of_this ();
|
||||
std::pair<const db::Pin *, const db::Pin *> pins ();
|
||||
bool derived_from_pins (const std::pair<const db::Pin *, const db::Pin *> &sp);
|
||||
|
||||
virtual std::pair<const db::SubCircuit *, const db::SubCircuit *> subcircuits_of_this ();
|
||||
std::pair<const db::SubCircuit *, const db::SubCircuit *> subcircuits ();
|
||||
bool derived_from_subcircuits (const std::pair<const db::SubCircuit *, const db::SubCircuit *> &sp);
|
||||
|
||||
virtual std::pair<const db::Net *, const db::Net *> nets_of_this ();
|
||||
std::pair<const db::Net *, const db::Net *> nets ();
|
||||
bool derived_from_nets (const std::pair<const db::Net *, const db::Net *> &np);
|
||||
|
||||
|
|
@ -167,6 +178,29 @@ private:
|
|||
virtual void do_ensure_children (NetlistBrowserModel *model) = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief An object describing the instantiation path of a net
|
||||
*/
|
||||
struct LAYBASIC_PUBLIC NetlistObjectPath
|
||||
{
|
||||
NetlistObjectPath () { }
|
||||
|
||||
bool operator== (const NetlistObjectPath &other) const
|
||||
{
|
||||
return root == other.root && path == other.path && net == other.net && device == other.device;
|
||||
}
|
||||
|
||||
bool operator!= (const NetlistObjectPath &other) const
|
||||
{
|
||||
return ! operator== (other);
|
||||
}
|
||||
|
||||
std::pair<const db::Circuit *, const db::Circuit *> root;
|
||||
std::list<std::pair<const db::SubCircuit *, const db::SubCircuit *> > path;
|
||||
std::pair<const db::Net *, const db::Net *> net;
|
||||
std::pair<const db::Device *, const db::Device *> device;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief The NetlistBrowserModel
|
||||
*
|
||||
|
|
@ -229,16 +263,17 @@ public:
|
|||
return mp_indexer.get ();
|
||||
}
|
||||
|
||||
std::pair<const db::Net *, const db::Net *> net_from_index (const QModelIndex &index) const;
|
||||
std::pair<const db::Net *, const db::Net *> net_from_index (const QModelIndex &index, bool include_parents = true) 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;
|
||||
std::pair<const db::Circuit *, const db::Circuit *> circuit_from_index (const QModelIndex &index, bool include_parents = true) 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;
|
||||
QModelIndex index_from_subcircuit (const std::pair<const db::SubCircuit *, const db::SubCircuit *> &subcircuits) const;
|
||||
|
||||
std::pair<const db::SubCircuit *, const db::SubCircuit *> subcircuit_from_index (const QModelIndex &index) const;
|
||||
std::pair<const db::SubCircuit *, const db::SubCircuit *> subcircuit_from_index (const QModelIndex &index, bool include_parents = true) const;
|
||||
|
||||
std::pair<const db::Device *, const db::Device *> device_from_index (const QModelIndex &index) const;
|
||||
std::pair<const db::Device *, const db::Device *> device_from_index (const QModelIndex &index, bool include_parents = true) const;
|
||||
|
||||
void set_item_visibility (QTreeView *view, bool show_all, bool with_warnings);
|
||||
|
||||
|
|
@ -253,7 +288,9 @@ public:
|
|||
QIcon icon_for_nets (const std::pair<const db::Net *, const db::Net *> &net) const;
|
||||
QIcon icon_for_connection (const std::pair<const db::Net *, const db::Net *> &net) const;
|
||||
|
||||
QModelIndex index_from_url (const QString &url);
|
||||
QModelIndex index_from_url (const QString &url) const;
|
||||
NetlistObjectPath netpath_from_index (const QModelIndex &index) const;
|
||||
QModelIndex index_from_netpath (const NetlistObjectPath &path);
|
||||
|
||||
private slots:
|
||||
void colors_changed ();
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ inline const db::Circuit *deref_circuit (const db::Circuit *obj)
|
|||
}
|
||||
|
||||
template <class Obj>
|
||||
static db::ICplxTrans
|
||||
static db::DCplxTrans
|
||||
trans_for (const Obj *objs, const db::Layout &ly, const db::Cell &cell, db::ContextCache &cc, const db::DCplxTrans &initial = db::DCplxTrans ())
|
||||
{
|
||||
db::DCplxTrans t = initial;
|
||||
|
|
@ -89,7 +89,6 @@ trans_for (const Obj *objs, const db::Layout &ly, const db::Cell &cell, db::Cont
|
|||
}
|
||||
|
||||
db::CplxTrans dbu_trans (ly.dbu ());
|
||||
db::ICplxTrans it = dbu_trans.inverted () * t * dbu_trans;
|
||||
|
||||
// The circuit may not be instantiated and still not be the top cell.
|
||||
// This happens if the subcell does not have connections. In this case
|
||||
|
|
@ -98,11 +97,11 @@ trans_for (const Obj *objs, const db::Layout &ly, const db::Cell &cell, db::Cont
|
|||
if (circuit && ly.is_valid_cell_index (circuit->cell_index ())) {
|
||||
std::pair<bool, db::ICplxTrans> tc = cc.find_layout_context (circuit->cell_index (), cell.cell_index ());
|
||||
if (tc.first) {
|
||||
it = tc.second * it;
|
||||
t = dbu_trans * tc.second * dbu_trans.inverted () * t;
|
||||
}
|
||||
}
|
||||
|
||||
return it;
|
||||
return t;
|
||||
}
|
||||
|
||||
NetlistBrowserPage::NetlistBrowserPage (QWidget * /*parent*/)
|
||||
|
|
@ -456,18 +455,11 @@ NetlistBrowserPage::selected_devices ()
|
|||
void
|
||||
NetlistBrowserPage::selection_changed ()
|
||||
{
|
||||
std::vector<const db::Net *> nets = selected_nets ();
|
||||
if (mp_info_dialog) {
|
||||
mp_info_dialog->set_nets (mp_database.get (), nets);
|
||||
}
|
||||
NetlistBrowserModel *model = dynamic_cast<NetlistBrowserModel *> (directory_tree->model ());
|
||||
tl_assert (model != 0);
|
||||
|
||||
std::vector<const db::Device *> devices = selected_devices ();
|
||||
|
||||
std::vector<const db::SubCircuit *> subcircuits = selected_subcircuits ();
|
||||
|
||||
std::vector<const db::Circuit *> circuits = selected_circuits ();
|
||||
|
||||
highlight (nets, devices, subcircuits, circuits);
|
||||
QModelIndex current = directory_tree->selectionModel ()->currentIndex ();
|
||||
highlight (model->netpath_from_index (current));
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -882,21 +874,15 @@ NetlistBrowserPage::setup_trees ()
|
|||
}
|
||||
|
||||
void
|
||||
NetlistBrowserPage::highlight (const std::vector<const db::Net *> &nets, const std::vector<const db::Device *> &devices, const std::vector<const db::SubCircuit *> &subcircuits, const std::vector<const db::Circuit *> &circuits)
|
||||
NetlistBrowserPage::highlight (const NetlistObjectPath &path)
|
||||
{
|
||||
if (nets != m_current_nets || devices != m_current_devices || subcircuits != m_current_subcircuits || circuits != m_current_circuits) {
|
||||
if (path != m_current_path) {
|
||||
|
||||
m_current_nets = nets;
|
||||
m_current_devices = devices;
|
||||
m_current_subcircuits = subcircuits;
|
||||
m_current_circuits = circuits;
|
||||
m_current_path = path;
|
||||
|
||||
clear_markers ();
|
||||
|
||||
if (! nets.empty () || ! devices.empty () || ! subcircuits.empty () || ! circuits.empty ()) {
|
||||
adjust_view ();
|
||||
update_highlights ();
|
||||
}
|
||||
adjust_view ();
|
||||
update_highlights ();
|
||||
|
||||
selection_changed ();
|
||||
|
||||
|
|
@ -926,7 +912,8 @@ bbox_for_device_abstract (const db::Layout *layout, const db::DeviceAbstract *de
|
|||
return db::Box ();
|
||||
}
|
||||
|
||||
return layout->cell (device_abstract->cell_index ()).bbox ().transformed (db::CplxTrans (layout->dbu ()).inverted () * trans * db::CplxTrans (layout->dbu ()));}
|
||||
return layout->cell (device_abstract->cell_index ()).bbox ().transformed (db::CplxTrans (layout->dbu ()).inverted () * trans * db::CplxTrans (layout->dbu ()));
|
||||
}
|
||||
|
||||
static db::Box
|
||||
bbox_for_circuit (const db::Layout *layout, const db::Circuit *circuit)
|
||||
|
|
@ -943,12 +930,6 @@ bbox_for_circuit (const db::Layout *layout, const db::Circuit *circuit)
|
|||
return layout->cell (circuit->cell_index ()).bbox ();
|
||||
}
|
||||
|
||||
static db::Box
|
||||
bbox_for_subcircuit (const db::Layout *layout, const db::SubCircuit *subcircuit)
|
||||
{
|
||||
return bbox_for_circuit (layout, subcircuit->circuit_ref ());
|
||||
}
|
||||
|
||||
void
|
||||
NetlistBrowserPage::adjust_view ()
|
||||
{
|
||||
|
|
@ -971,51 +952,67 @@ NetlistBrowserPage::adjust_view ()
|
|||
return;
|
||||
}
|
||||
|
||||
const db::Circuit *circuit = m_current_path.root.first;
|
||||
db::DCplxTrans trans;
|
||||
|
||||
db::Box bbox;
|
||||
if (circuit) {
|
||||
|
||||
for (std::vector<const db::Net *>::const_iterator net = m_current_nets.begin (); net != m_current_nets.end (); ++net) {
|
||||
trans = trans_for (circuit, *layout, *cell, m_cell_context_cache, db::DCplxTrans ());
|
||||
|
||||
db::ICplxTrans net_trans = trans_for (*net, *layout, *cell, m_cell_context_cache);
|
||||
for (std::list<std::pair<const db::SubCircuit *, const db::SubCircuit *> >::const_iterator p = m_current_path.path.begin (); p != m_current_path.path.end () && circuit; ++p) {
|
||||
if (p->first) {
|
||||
circuit = p->first->circuit_ref ();
|
||||
trans = trans * p->first->trans ();
|
||||
} else {
|
||||
circuit = 0;
|
||||
}
|
||||
}
|
||||
|
||||
db::cell_index_type cell_index = (*net)->circuit ()->cell_index ();
|
||||
size_t cluster_id = (*net)->cluster_id ();
|
||||
}
|
||||
|
||||
const db::Connectivity &conn = mp_database->connectivity ();
|
||||
for (db::Connectivity::layer_iterator layer = conn.begin_layers (); layer != conn.end_layers (); ++layer) {
|
||||
db::DBox bbox;
|
||||
|
||||
db::Box layer_bbox;
|
||||
db::recursive_cluster_shape_iterator<db::NetShape> shapes (mp_database->net_clusters (), *layer, cell_index, cluster_id);
|
||||
while (! shapes.at_end ()) {
|
||||
layer_bbox += shapes->bbox ();
|
||||
++shapes;
|
||||
if (circuit) {
|
||||
|
||||
db::Box ebox;
|
||||
|
||||
const db::Device *device = m_current_path.device.first;
|
||||
const db::Net *net = m_current_path.net.first;
|
||||
|
||||
if (device) {
|
||||
|
||||
ebox += bbox_for_device_abstract (layout, device->device_abstract (), db::DCplxTrans ());
|
||||
|
||||
const std::vector<db::DeviceAbstractRef> &oda = device->other_abstracts ();
|
||||
for (std::vector<db::DeviceAbstractRef>::const_iterator a = oda.begin (); a != oda.end (); ++a) {
|
||||
ebox += bbox_for_device_abstract (layout, a->device_abstract, a->trans);
|
||||
}
|
||||
|
||||
bbox += net_trans * layer_bbox;
|
||||
} else if (net) {
|
||||
|
||||
db::cell_index_type cell_index = net->circuit ()->cell_index ();
|
||||
size_t cluster_id = net->cluster_id ();
|
||||
|
||||
const db::Connectivity &conn = mp_database->connectivity ();
|
||||
for (db::Connectivity::layer_iterator layer = conn.begin_layers (); layer != conn.end_layers (); ++layer) {
|
||||
|
||||
db::Box layer_bbox;
|
||||
db::recursive_cluster_shape_iterator<db::NetShape> shapes (mp_database->net_clusters (), *layer, cell_index, cluster_id);
|
||||
while (! shapes.at_end ()) {
|
||||
layer_bbox += shapes->bbox ();
|
||||
++shapes;
|
||||
}
|
||||
|
||||
ebox += layer_bbox;
|
||||
|
||||
}
|
||||
|
||||
} else if (circuit) {
|
||||
ebox += bbox_for_circuit (layout, circuit);
|
||||
}
|
||||
|
||||
}
|
||||
bbox = trans * db::CplxTrans (layout->dbu ()) * ebox;
|
||||
|
||||
for (std::vector<const db::Device *>::const_iterator device = m_current_devices.begin (); device != m_current_devices.end (); ++device) {
|
||||
|
||||
db::ICplxTrans trans = trans_for (*device, *layout, *cell, m_cell_context_cache, (*device)->trans ());
|
||||
|
||||
bbox += trans * bbox_for_device_abstract (layout, (*device)->device_abstract (), db::DCplxTrans ());
|
||||
|
||||
const std::vector<db::DeviceAbstractRef> &oda = (*device)->other_abstracts ();
|
||||
for (std::vector<db::DeviceAbstractRef>::const_iterator a = oda.begin (); a != oda.end (); ++a) {
|
||||
bbox += trans * bbox_for_device_abstract (layout, a->device_abstract, a->trans);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for (std::vector<const db::SubCircuit *>::const_iterator subcircuit = m_current_subcircuits.begin (); subcircuit != m_current_subcircuits.end (); ++subcircuit) {
|
||||
bbox += trans_for (*subcircuit, *layout, *cell, m_cell_context_cache, (*subcircuit)->trans ()) * bbox_for_subcircuit (layout, *subcircuit);
|
||||
}
|
||||
|
||||
for (std::vector<const db::Circuit *>::const_iterator circuit = m_current_circuits.begin (); circuit != m_current_circuits.end (); ++circuit) {
|
||||
bbox += trans_for (*circuit, *layout, *cell, m_cell_context_cache, db::DCplxTrans ()) * bbox_for_circuit (layout, *circuit);
|
||||
}
|
||||
|
||||
if (! bbox.empty ()) {
|
||||
|
|
@ -1023,9 +1020,8 @@ NetlistBrowserPage::adjust_view ()
|
|||
std::vector<db::DCplxTrans> tv = mp_view->cv_transform_variants (m_cv_index);
|
||||
|
||||
db::DBox tv_bbox;
|
||||
db::DBox dbu_bbox = db::CplxTrans (layout->dbu ()) * bbox;
|
||||
for (std::vector<db::DCplxTrans>::const_iterator t = tv.begin (); t != tv.end (); ++t) {
|
||||
tv_bbox += *t * dbu_bbox;
|
||||
tv_bbox += *t * bbox;
|
||||
}
|
||||
|
||||
if (m_window == lay::NetlistBrowserConfig::FitNet) {
|
||||
|
|
@ -1063,12 +1059,10 @@ bool
|
|||
NetlistBrowserPage::produce_highlights_for_device (const db::Device *device, size_t &n_markers, const std::vector<db::DCplxTrans> &tv)
|
||||
{
|
||||
const db::Layout *layout = mp_database->internal_layout ();
|
||||
const db::Cell *cell = mp_database->internal_top_cell ();
|
||||
db::ICplxTrans device_trans = trans_for (device, *layout, *cell, m_cell_context_cache, device->trans ());
|
||||
|
||||
QColor color = make_valid_color (m_colorizer.marker_color ());
|
||||
|
||||
db::Box device_bbox = bbox_for_device_abstract (layout, device->device_abstract (), db::DCplxTrans ());
|
||||
db::Box device_bbox = bbox_for_device_abstract (layout, device->device_abstract (), device->trans ());
|
||||
if (! device_bbox.empty ()) {
|
||||
|
||||
if (n_markers == m_max_shape_count) {
|
||||
|
|
@ -1078,7 +1072,7 @@ NetlistBrowserPage::produce_highlights_for_device (const db::Device *device, siz
|
|||
++n_markers;
|
||||
|
||||
mp_markers.push_back (new lay::Marker (mp_view, m_cv_index));
|
||||
mp_markers.back ()->set (device_bbox, device_trans, tv);
|
||||
mp_markers.back ()->set (device_bbox, db::ICplxTrans (), tv);
|
||||
mp_markers.back ()->set_color (color);
|
||||
mp_markers.back ()->set_frame_color (color);
|
||||
configure_marker (mp_markers.back (), false);
|
||||
|
|
@ -1088,7 +1082,7 @@ NetlistBrowserPage::produce_highlights_for_device (const db::Device *device, siz
|
|||
const std::vector<db::DeviceAbstractRef> &oda = device->other_abstracts ();
|
||||
for (std::vector<db::DeviceAbstractRef>::const_iterator a = oda.begin (); a != oda.end (); ++a) {
|
||||
|
||||
db::Box da_box = bbox_for_device_abstract (layout, a->device_abstract, a->trans);
|
||||
db::Box da_box = bbox_for_device_abstract (layout, a->device_abstract, device->trans () * a->trans);
|
||||
if (! da_box.empty ()) {
|
||||
|
||||
if (n_markers == m_max_shape_count) {
|
||||
|
|
@ -1098,7 +1092,7 @@ NetlistBrowserPage::produce_highlights_for_device (const db::Device *device, siz
|
|||
++n_markers;
|
||||
|
||||
mp_markers.push_back (new lay::Marker (mp_view, m_cv_index));
|
||||
mp_markers.back ()->set (da_box, device_trans, tv);
|
||||
mp_markers.back ()->set (da_box, db::ICplxTrans (), tv);
|
||||
mp_markers.back ()->set_color (color);
|
||||
mp_markers.back ()->set_frame_color (color);
|
||||
configure_marker (mp_markers.back (), false);
|
||||
|
|
@ -1110,40 +1104,10 @@ NetlistBrowserPage::produce_highlights_for_device (const db::Device *device, siz
|
|||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
NetlistBrowserPage::produce_highlights_for_subcircuit (const db::SubCircuit *subcircuit, size_t &n_markers, const std::vector<db::DCplxTrans> &tv)
|
||||
{
|
||||
const db::Layout *layout = mp_database->internal_layout ();
|
||||
const db::Cell *cell = mp_database->internal_top_cell ();
|
||||
db::ICplxTrans subcircuit_trans = trans_for (subcircuit, *layout, *cell, m_cell_context_cache, subcircuit->trans ());
|
||||
|
||||
QColor color = make_valid_color (m_colorizer.marker_color ());
|
||||
db::Box circuit_bbox = bbox_for_subcircuit (layout, subcircuit);
|
||||
if (circuit_bbox.empty ()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (n_markers == m_max_shape_count) {
|
||||
return true;
|
||||
}
|
||||
|
||||
++n_markers;
|
||||
|
||||
mp_markers.push_back (new lay::Marker (mp_view, m_cv_index));
|
||||
mp_markers.back ()->set (circuit_bbox, subcircuit_trans, tv);
|
||||
mp_markers.back ()->set_color (color);
|
||||
mp_markers.back ()->set_frame_color (color);
|
||||
configure_marker (mp_markers.back (), false);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
NetlistBrowserPage::produce_highlights_for_circuit (const db::Circuit *circuit, size_t &n_markers, const std::vector<db::DCplxTrans> &tv)
|
||||
{
|
||||
const db::Layout *layout = mp_database->internal_layout ();
|
||||
const db::Cell *cell = mp_database->internal_top_cell ();
|
||||
db::ICplxTrans circuit_trans = trans_for (circuit, *layout, *cell, m_cell_context_cache, db::DCplxTrans ());
|
||||
|
||||
QColor color = make_valid_color (m_colorizer.marker_color ());
|
||||
db::Box circuit_bbox = bbox_for_circuit (layout, circuit);
|
||||
|
|
@ -1158,7 +1122,7 @@ NetlistBrowserPage::produce_highlights_for_circuit (const db::Circuit *circuit,
|
|||
++n_markers;
|
||||
|
||||
mp_markers.push_back (new lay::Marker (mp_view, m_cv_index));
|
||||
mp_markers.back ()->set (circuit_bbox, circuit_trans, tv);
|
||||
mp_markers.back ()->set (circuit_bbox, db::ICplxTrans (), tv);
|
||||
mp_markers.back ()->set_color (color);
|
||||
mp_markers.back ()->set_frame_color (color);
|
||||
configure_marker (mp_markers.back (), false);
|
||||
|
|
@ -1170,8 +1134,6 @@ bool
|
|||
NetlistBrowserPage::produce_highlights_for_net (const db::Net *net, size_t &n_markers, const std::map<db::LayerProperties, lay::LayerPropertiesConstIterator> &display_by_lp, const std::vector<db::DCplxTrans> &tv)
|
||||
{
|
||||
const db::Layout *layout = mp_database->internal_layout ();
|
||||
const db::Cell *cell = mp_database->internal_top_cell ();
|
||||
db::ICplxTrans net_trans = trans_for (net, *layout, *cell, m_cell_context_cache);
|
||||
|
||||
db::cell_index_type cell_index = net->circuit ()->cell_index ();
|
||||
size_t cluster_id = net->cluster_id ();
|
||||
|
|
@ -1197,7 +1159,7 @@ NetlistBrowserPage::produce_highlights_for_net (const db::Net *net, size_t &n_ma
|
|||
}
|
||||
|
||||
mp_markers.push_back (new lay::Marker (mp_view, m_cv_index));
|
||||
mp_markers.back ()->set (shapes->polygon_ref (), net_trans * shapes.trans (), tv);
|
||||
mp_markers.back ()->set (shapes->polygon_ref (), shapes.trans (), tv);
|
||||
|
||||
if (net_color.isValid ()) {
|
||||
|
||||
|
|
@ -1272,10 +1234,31 @@ NetlistBrowserPage::update_highlights ()
|
|||
const db::Layout &original_layout = mp_view->cellview (m_cv_index)->layout ();
|
||||
|
||||
const db::Layout *layout = mp_database->internal_layout ();
|
||||
if (! layout) {
|
||||
const db::Cell *cell = mp_database->internal_top_cell ();
|
||||
if (! layout || ! cell) {
|
||||
return;
|
||||
}
|
||||
|
||||
// compute the transformation supplied by the path
|
||||
|
||||
const db::Circuit *circuit = m_current_path.root.first;
|
||||
db::DCplxTrans trans;
|
||||
|
||||
if (circuit) {
|
||||
|
||||
trans = trans_for (circuit, *layout, *cell, m_cell_context_cache, db::DCplxTrans ());
|
||||
|
||||
for (std::list<std::pair<const db::SubCircuit *, const db::SubCircuit *> >::const_iterator p = m_current_path.path.begin (); p != m_current_path.path.end () && circuit; ++p) {
|
||||
if (p->first) {
|
||||
circuit = p->first->circuit_ref ();
|
||||
trans = trans * p->first->trans ();
|
||||
} else {
|
||||
circuit = 0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// a map of display properties vs. layer properties
|
||||
|
||||
std::map<db::LayerProperties, lay::LayerPropertiesConstIterator> display_by_lp;
|
||||
|
|
@ -1289,32 +1272,18 @@ NetlistBrowserPage::update_highlights ()
|
|||
|
||||
// correct DBU differences between the storage layout and the original layout
|
||||
for (std::vector<db::DCplxTrans>::iterator t = tv.begin (); t != tv.end (); ++t) {
|
||||
*t = *t * db::DCplxTrans (layout->dbu () / original_layout.dbu ());
|
||||
*t = *t * trans * db::DCplxTrans (layout->dbu () / original_layout.dbu ());
|
||||
}
|
||||
|
||||
size_t n_markers = 0;
|
||||
bool not_all_shapes_are_shown = false;
|
||||
|
||||
for (std::vector<const db::Net *>::const_iterator net = m_current_nets.begin (); net != m_current_nets.end () && ! not_all_shapes_are_shown; ++net) {
|
||||
if ((*net)->circuit ()) {
|
||||
not_all_shapes_are_shown = produce_highlights_for_net (*net, n_markers, display_by_lp, tv);
|
||||
}
|
||||
}
|
||||
|
||||
for (std::vector<const db::Device *>::const_iterator device = m_current_devices.begin (); device != m_current_devices.end () && ! not_all_shapes_are_shown; ++device) {
|
||||
if ((*device)->circuit ()) {
|
||||
not_all_shapes_are_shown = produce_highlights_for_device (*device, n_markers, tv);
|
||||
}
|
||||
}
|
||||
|
||||
for (std::vector<const db::SubCircuit *>::const_iterator subcircuit = m_current_subcircuits.begin (); subcircuit != m_current_subcircuits.end () && ! not_all_shapes_are_shown; ++subcircuit) {
|
||||
if ((*subcircuit)->circuit ()) {
|
||||
not_all_shapes_are_shown = produce_highlights_for_subcircuit (*subcircuit, n_markers, tv);
|
||||
}
|
||||
}
|
||||
|
||||
for (std::vector<const db::Circuit *>::const_iterator circuit = m_current_circuits.begin (); circuit != m_current_circuits.end () && ! not_all_shapes_are_shown; ++circuit) {
|
||||
not_all_shapes_are_shown = produce_highlights_for_circuit (*circuit, n_markers, tv);
|
||||
if (m_current_path.net.first) {
|
||||
not_all_shapes_are_shown = produce_highlights_for_net (m_current_path.net.first, n_markers, display_by_lp, tv);
|
||||
} else if (m_current_path.device.first) {
|
||||
not_all_shapes_are_shown = produce_highlights_for_device (m_current_path.device.first, n_markers, tv);
|
||||
} else if (circuit) {
|
||||
not_all_shapes_are_shown = produce_highlights_for_circuit (circuit, n_markers, tv);
|
||||
}
|
||||
|
||||
if (not_all_shapes_are_shown) {
|
||||
|
|
|
|||
|
|
@ -234,6 +234,9 @@ private:
|
|||
std::vector <lay::Marker *> mp_markers;
|
||||
bool m_enable_updates;
|
||||
bool m_update_needed;
|
||||
// @@@ TODO: make multiple ...
|
||||
lay::NetlistObjectPath m_current_path;
|
||||
// @@@ TODO: remove
|
||||
std::vector<const db::Net *> m_current_nets;
|
||||
std::vector<const db::Device *> m_current_devices;
|
||||
std::vector<const db::SubCircuit *> m_current_subcircuits;
|
||||
|
|
@ -248,7 +251,7 @@ private:
|
|||
void navigate_to (const QModelIndex &index, bool forward = true);
|
||||
void adjust_view ();
|
||||
void clear_markers ();
|
||||
void highlight (const std::vector<const db::Net *> &nets, const std::vector<const db::Device *> &devices, const std::vector<const db::SubCircuit *> &subcircuits, const std::vector<const db::Circuit *> &circuits);
|
||||
void highlight (const lay::NetlistObjectPath &path);
|
||||
std::vector<const db::Net *> selected_nets ();
|
||||
std::vector<const db::Device *> selected_devices ();
|
||||
std::vector<const db::SubCircuit *> selected_subcircuits ();
|
||||
|
|
@ -258,7 +261,6 @@ private:
|
|||
QColor make_valid_color (const QColor &color);
|
||||
bool produce_highlights_for_net(const db::Net *net, size_t &n_markers, const std::map<db::LayerProperties, lay::LayerPropertiesConstIterator> &display_by_lp, const std::vector<db::DCplxTrans> &tv);
|
||||
bool produce_highlights_for_device (const db::Device *device, size_t &n_markers, const std::vector<db::DCplxTrans> &tv);
|
||||
bool produce_highlights_for_subcircuit (const db::SubCircuit *subcircuit, size_t &n_markers, const std::vector<db::DCplxTrans> &tv);
|
||||
bool produce_highlights_for_circuit (const db::Circuit *circuit, size_t &n_markers, const std::vector<db::DCplxTrans> &tv);
|
||||
void configure_marker (lay::Marker *marker, bool with_fill);
|
||||
void rerun_macro ();
|
||||
|
|
|
|||
|
|
@ -123,8 +123,8 @@ TEST (1)
|
|||
|
||||
QModelIndex inv2PinOutIndexNet = model->index (0, 0, inv2PinOutIndex);
|
||||
EXPECT_EQ (model->parent (inv2PinOutIndexNet) == inv2PinOutIndex, true);
|
||||
EXPECT_EQ (model->hasChildren (inv2PinOutIndexNet), false);
|
||||
EXPECT_EQ (model->rowCount (inv2PinOutIndexNet), 0);
|
||||
EXPECT_EQ (model->hasChildren (inv2PinOutIndexNet), true);
|
||||
EXPECT_EQ (model->rowCount (inv2PinOutIndexNet), 3);
|
||||
|
||||
// NOUT net has 1 pin, 2 devices, 0 subcircuits
|
||||
QModelIndex inv2NOutIndex = model->index (1, 0, model->index (1, 0, inv2Index));
|
||||
|
|
@ -206,11 +206,12 @@ TEST (1)
|
|||
QModelIndex ringoSubcircuit1Index = model->index (0, 0, sn_subcircuits);
|
||||
EXPECT_EQ (model->parent (ringoSubcircuit1Index) == sn_subcircuits, true);
|
||||
EXPECT_EQ (model->hasChildren (ringoSubcircuit1Index), true);
|
||||
EXPECT_EQ (model->rowCount (ringoSubcircuit1Index), 5);
|
||||
EXPECT_EQ (model->rowCount (ringoSubcircuit1Index), 6);
|
||||
|
||||
EXPECT_EQ (tl::to_string (model->data (model->index (2, 0, ringoSubcircuit1Index), Qt::UserRole).toString ()), "OUT");
|
||||
EXPECT_EQ (tl::to_string (model->data (model->index (2, 0, ringoSubcircuit1Index), Qt::DisplayRole).toString ()), "OUT");
|
||||
EXPECT_EQ (tl::to_string (model->data (model->index (2, 2, ringoSubcircuit1Index), Qt::DisplayRole).toString ()), "");
|
||||
EXPECT_EQ (tl::to_string (model->data (model->index (5, 0, ringoSubcircuit1Index), Qt::DisplayRole).toString ()), "INV2");
|
||||
|
||||
QModelIndex ringoSubcircuit1OutPinIndex = model->index (2, 0, ringoSubcircuit1Index);
|
||||
EXPECT_EQ (model->parent (ringoSubcircuit1OutPinIndex) == ringoSubcircuit1Index, true);
|
||||
|
|
@ -287,7 +288,7 @@ TEST (2)
|
|||
// INV2, pin 0 has one net node
|
||||
EXPECT_EQ (tl::to_string (model->data (model->index (0, 0, inv2Pin0Index), Qt::UserRole).toString ()), "$1|1");
|
||||
EXPECT_EQ (tl::to_string (model->data (model->index (0, 0, inv2Pin0Index), Qt::DisplayRole).toString ()), "$1 ⇔ 1");
|
||||
EXPECT_EQ (tl::to_string (model->data (model->index (0, 2, inv2Pin0Index), Qt::DisplayRole).toString ()), "<a href='int:netlist?path=1,1,0'>$1</a>");
|
||||
EXPECT_EQ (tl::to_string (model->data (model->index (0, 2, inv2Pin0Index), Qt::DisplayRole).toString ()), "$1 (2)");
|
||||
std::pair<const db::Net *, const db::Net *> nets = model->net_from_index (model->index (0, 0, inv2Pin0Index));
|
||||
EXPECT_EQ (nets.first != 0, true);
|
||||
if (nets.first != 0) {
|
||||
|
|
@ -297,7 +298,7 @@ TEST (2)
|
|||
if (nets.second != 0) {
|
||||
EXPECT_EQ (nets.second->expanded_name (), "1");
|
||||
}
|
||||
EXPECT_EQ (tl::to_string (model->data (model->index (0, 3, inv2Pin0Index), Qt::DisplayRole).toString ()), "<a href='int:netlist?path=1,1,0'>1</a>");
|
||||
EXPECT_EQ (tl::to_string (model->data (model->index (0, 3, inv2Pin0Index), Qt::DisplayRole).toString ()), "1 (2)");
|
||||
|
||||
// first of nets in INV2 circuit
|
||||
EXPECT_EQ (tl::to_string (model->data (model->index (0, 0, sn_nets), Qt::UserRole).toString ()), "$1|1");
|
||||
|
|
@ -422,3 +423,59 @@ TEST (2)
|
|||
EXPECT_EQ (tl::to_string (model->data (model->index (0, 2, inv2PairNet0SubCircuit0Index), Qt::DisplayRole).toString ()), "<a href='int:netlist?path=2,1,5'>$7</a>");
|
||||
EXPECT_EQ (tl::to_string (model->data (model->index (0, 3, inv2PairNet0SubCircuit0Index), Qt::DisplayRole).toString ()), "");
|
||||
}
|
||||
|
||||
TEST (3)
|
||||
{
|
||||
db::LayoutToNetlist l2n;
|
||||
l2n.load (tl::testsrc () + "/testdata/lay/l2n_browser.l2n");
|
||||
|
||||
lay::NetColorizer colorizer;
|
||||
std::auto_ptr<lay::NetlistBrowserModel> model (new lay::NetlistBrowserModel (0, &l2n, &colorizer));
|
||||
|
||||
db::Circuit *root = l2n.netlist ()->circuit_by_name ("RINGO");
|
||||
EXPECT_EQ (root != 0, true);
|
||||
|
||||
lay::NetlistObjectPath path;
|
||||
EXPECT_EQ (model->index_from_netpath (path).isValid (), false);
|
||||
|
||||
path.root.first = root;
|
||||
|
||||
db::Net *net = root->net_by_name ("FB");
|
||||
EXPECT_EQ (net != 0, true);
|
||||
|
||||
path.net.first = net;
|
||||
|
||||
QModelIndex index = model->index_from_netpath (path);
|
||||
EXPECT_EQ (index.isValid (), true);
|
||||
|
||||
EXPECT_EQ (tl::to_string (model->data (index, Qt::UserRole).toString ()), "FB");
|
||||
}
|
||||
|
||||
TEST (4)
|
||||
{
|
||||
db::LayoutToNetlist l2n;
|
||||
l2n.load (tl::testsrc () + "/testdata/lay/l2n_browser.l2n");
|
||||
|
||||
lay::NetColorizer colorizer;
|
||||
std::auto_ptr<lay::NetlistBrowserModel> model (new lay::NetlistBrowserModel (0, &l2n, &colorizer));
|
||||
|
||||
db::Circuit *root = l2n.netlist ()->circuit_by_name ("RINGO");
|
||||
EXPECT_EQ (root != 0, true);
|
||||
|
||||
lay::NetlistObjectPath path;
|
||||
path.root.first = root;
|
||||
|
||||
db::SubCircuit *sc1 = root->begin_subcircuits ().operator-> ();
|
||||
EXPECT_EQ (sc1 != 0, true);
|
||||
path.path.push_back (std::make_pair (sc1, (db::SubCircuit *) 0));
|
||||
|
||||
db::Net *net = sc1->circuit_ref ()->net_by_name ("NOUT");
|
||||
EXPECT_EQ (net != 0, true);
|
||||
|
||||
path.net.first = net;
|
||||
|
||||
QModelIndex index = model->index_from_netpath (path);
|
||||
EXPECT_EQ (index.isValid (), true);
|
||||
|
||||
EXPECT_EQ (tl::to_string (model->data (index, Qt::UserRole).toString ()), "NOUT");
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue