WIP: netlist browser tree, highlights etc.

This commit is contained in:
Matthias Koefferlein 2020-07-12 01:22:22 +02:00
parent 62ed7b9def
commit f00f5c76b8
5 changed files with 503 additions and 223 deletions

View File

@ -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 ();
}
}

View File

@ -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 ();

View File

@ -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) {

View File

@ -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 ();

View File

@ -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");
}