diff --git a/src/laybasic/laybasic/layNetlistBrowserModel.cc b/src/laybasic/laybasic/layNetlistBrowserModel.cc index 24d0fcc04..0cbe29ef0 100644 --- a/src/laybasic/laybasic/layNetlistBrowserModel.cc +++ b/src/laybasic/laybasic/layNetlistBrowserModel.cc @@ -158,64 +158,138 @@ NetColorizer::color_of_net (const db::Net *net) const namespace { template - struct sort_by_name + struct sort_single_by_name { - bool operator() (const Obj *a, const Obj *b) const + inline bool operator() (const Obj *a, const Obj *b) const { return a->name () < b->name (); } }; template - struct sort_by_expanded_name + struct sort_single_by_expanded_name { - bool operator() (const Obj *a, const Obj *b) const + inline bool operator() (const Obj *a, const Obj *b) const { return a->expanded_name () < b->expanded_name (); } }; template - struct sort_by_pin_name + struct sort_single_by_pin_name { - bool operator() (const Obj *a, const Obj *b) const + inline bool operator() (const Obj *a, const Obj *b) const { return a->pin ()->expanded_name () < b->pin ()->expanded_name (); } }; template - struct sort_by_terminal_id + struct sort_single_by_terminal_id { - bool operator() (const Obj *a, const Obj *b) const + inline bool operator() (const Obj *a, const Obj *b) const { return a->terminal_id () < b->terminal_id (); } }; + template + struct sort_with_null + { + inline bool operator() (const Obj *a, const Obj *b) const + { + SortBy order; + if ((a != 0) != (b != 0)) { + return (a != 0) < (b != 0); + } + if (a) { + if (order (a, b)) { + return true; + } else if (order (b, a)) { + return false; + } + } + return false; + } + }; + + template + struct sort_pair + { + bool operator() (const std::pair &a, const std::pair &b) const + { + SortBy order; + if (order (a.first, b.first)) { + return true; + } else if (order (b.first, a.first)) { + return false; + } + return order (a.second, b.second); + } + }; + + template + struct sort_by_name + : public sort_pair > > + { + // .. nothing yet .. + }; + + template + struct sort_by_expanded_name + : public sort_pair > > + { + // .. nothing yet .. + }; + + template + struct sort_by_pin_name + : public sort_pair > > + { + // .. nothing yet .. + }; + + template + struct sort_by_terminal_id + : public sort_pair > > + { + // .. nothing yet .. + }; + +} + +template +static void fill_map (std::vector > &map, const Iter &begin1, const Iter &end1, const Iter &begin2, const Iter &end2, const SortBy &sorter) +{ + size_t n1 = 0, n2 = 0; + for (Iter i = begin1; i != end1; ++i) { + ++n1; + } + for (Iter i = begin2; i != end2; ++i) { + ++n2; + } + map.resize (std::max (n1, n2), typename std::pair (0, 0)); + + typename std::vector >::iterator j; + j = map.begin (); + for (Iter i = begin1; i != end1; ++i, ++j) { + j->first = i.operator-> (); + } + j = map.begin (); + for (Iter i = begin2; i != end2; ++i, ++j) { + j->second = i.operator-> (); + } + + std::sort (map.begin (), map.end (), sorter); } template -static const Attr *attr_by_object_and_index (const Obj *obj, size_t index, const Iter &begin, const Iter &end, std::map > &cache, const SortBy &sorter) +static std::pair attr_by_object_and_index (const std::pair &obj, size_t index, const Iter &begin1, const Iter &end1, const Iter &begin2, const Iter &end2, std::map, std::vector > > &cache, const SortBy &sorter) { - typename std::map >::iterator cc = cache.find (obj); + typename std::map, std::vector > >::iterator cc = cache.find (obj); if (cc == cache.end ()) { - - cc = cache.insert (std::make_pair (obj, std::vector ())).first; - - std::vector &map = cc->second; - - size_t n = 0; - for (Iter i = begin; i != end; ++i) { - ++n; - } - map.reserve (n); - for (Iter i = begin; i != end; ++i) { - map.push_back (i.operator-> ()); - } - - std::sort (map.begin (), map.end (), sorter); - + cc = cache.insert (std::make_pair (obj, std::vector > ())).first; + fill_map (cc->second, begin1, end1, begin2, end2, sorter); } tl_assert (index < cc->second.size ()); @@ -223,30 +297,21 @@ static const Attr *attr_by_object_and_index (const Obj *obj, size_t index, const } template -static size_t index_from_attr (const Attr *attr, const Iter &begin, const Iter &end, std::map &cache, const SortBy &sorter) +static size_t index_from_attr (const std::pair &attrs, const Iter &begin1, const Iter &end1, const Iter &begin2, const Iter &end2, std::map, size_t> &cache, const SortBy &sorter) { - typename std::map::iterator cc = cache.find (attr); + typename std::map, size_t>::iterator cc = cache.find (attrs); if (cc != cache.end ()) { return cc->second; } - std::vector map; - size_t n = 0; - for (Iter i = begin; i != end; ++i) { - ++n; - } - map.reserve (n); - for (Iter i = begin; i != end; ++i) { - map.push_back (i.operator-> ()); - } - - std::sort (map.begin (), map.end (), sorter); + std::vector > map; + fill_map (map, begin1, end1, begin2, end2, sorter); for (size_t i = 0; i < map.size (); ++i) { cache.insert (std::make_pair (map [i], i)); } - cc = cache.find (attr); + cc = cache.find (attrs); tl_assert (cc != cache.end ()); return cc->second; } @@ -260,20 +325,45 @@ public: IndexedNetlistModel () { } virtual ~IndexedNetlistModel () { } - virtual const db::Circuit *circuit_from_index (size_t index) const = 0; - virtual const db::Net *net_from_index (const db::Circuit *circuit, size_t index) const = 0; - virtual const db::NetSubcircuitPinRef *net_subcircuit_pinref_from_index (const db::Net *net, size_t index) const = 0; - virtual const db::NetTerminalRef *net_terminalref_from_index (const db::Net *net, size_t index) const = 0; - virtual const db::NetPinRef *net_pinref_from_index (const db::Net *net, size_t index) const = 0; - virtual const db::Device *device_from_index (const db::Circuit *circuit, size_t index) const = 0; - virtual const db::Pin *pin_from_index (const db::Circuit *circuit, size_t index) const = 0; - virtual const db::SubCircuit *subcircuit_from_index (const db::Circuit *circuit, size_t index) const = 0; + virtual bool is_single () const = 0; - virtual size_t circuit_index (const db::Circuit *circuit) const = 0; - virtual size_t net_index (const db::Net *net) const = 0; - virtual size_t device_index (const db::Device *device) const = 0; - virtual size_t pin_index (const db::Pin *pin, const db::Circuit *circuit) const = 0; - virtual size_t subcircuit_index (const db::SubCircuit *subcircuit) const = 0; + typedef std::pair circuit_pair; + typedef std::pair net_pair; + typedef std::pair net_subcircuit_pin_pair; + typedef std::pair net_terminal_pair; + typedef std::pair net_pin_pair; + typedef std::pair device_pair; + typedef std::pair pin_pair; + typedef std::pair subcircuit_pair; + + virtual size_t circuit_count () const = 0; + virtual size_t net_count (const circuit_pair &circuits) const = 0; + virtual size_t net_terminal_count (const net_pair &nets) const = 0; + virtual size_t net_subcircuit_pin_count (const net_pair &nets) const = 0; + virtual size_t net_pin_count (const net_pair &nets) const = 0; + virtual size_t device_count (const circuit_pair &circuits) const = 0; + virtual size_t pin_count (const circuit_pair &circuits) const = 0; + virtual size_t subcircuit_count (const circuit_pair &circuits) const = 0; + + virtual circuit_pair parent_of (const net_pair &net_pair) const = 0; + virtual circuit_pair parent_of (const device_pair &device_pair) const = 0; + virtual circuit_pair parent_of (const subcircuit_pair &subcircuit_pair) const = 0; + + virtual circuit_pair circuit_from_index (size_t index) const = 0; + virtual net_pair net_from_index (const circuit_pair &circuits, size_t index) const = 0; + virtual const db::Net *second_net_for (const db::Net *first) const = 0; + virtual net_subcircuit_pin_pair net_subcircuit_pinref_from_index (const net_pair &nets, size_t index) const = 0; + virtual net_terminal_pair net_terminalref_from_index (const net_pair &nets, size_t index) const = 0; + virtual net_pin_pair net_pinref_from_index (const net_pair &nets, size_t index) const = 0; + virtual device_pair device_from_index (const circuit_pair &circuits, size_t index) const = 0; + virtual pin_pair pin_from_index (const circuit_pair &circuits, size_t index) const = 0; + virtual subcircuit_pair subcircuit_from_index (const circuit_pair &circuits, size_t index) const = 0; + + virtual size_t circuit_index (const circuit_pair &circuits) const = 0; + virtual size_t net_index (const net_pair &nets) const = 0; + virtual size_t device_index (const device_pair &devices) const = 0; + virtual size_t pin_index (const pin_pair &pins, const circuit_pair &circuits) const = 0; + virtual size_t subcircuit_index (const subcircuit_pair &subcircuits) const = 0; private: IndexedNetlistModel &operator= (const IndexedNetlistModel &); @@ -292,90 +382,186 @@ public: virtual ~SingleIndexedNetlistModel () { } - const db::Circuit *circuit_from_index (size_t index) const + virtual bool is_single () const { - return attr_by_object_and_index (mp_netlist, index, mp_netlist->begin_circuits (), mp_netlist->end_circuits (), m_circuit_by_index, sort_by_name ()); + return true; } - const db::Net *net_from_index (const db::Circuit *circuit, size_t index) const + virtual size_t circuit_count () const { - return attr_by_object_and_index (circuit, index, circuit->begin_nets (), circuit->end_nets (), m_net_by_circuit_and_index, sort_by_expanded_name ()); + return mp_netlist->circuit_count (); } - const db::NetSubcircuitPinRef *net_subcircuit_pinref_from_index (const db::Net *net, size_t index) const + virtual size_t net_count (const circuit_pair &circuits) const { - return attr_by_object_and_index (net, index, net->begin_subcircuit_pins (), net->end_subcircuit_pins (), m_subcircuit_pinref_by_net_and_index, sort_by_pin_name ()); + return circuits.first->net_count (); } - const db::NetTerminalRef *net_terminalref_from_index (const db::Net *net, size_t index) const + virtual size_t net_terminal_count (const net_pair &nets) const { - return attr_by_object_and_index (net, index, net->begin_terminals (), net->end_terminals (), m_terminalref_by_net_and_index, sort_by_terminal_id ()); + return nets.first->terminal_count (); } - const db::NetPinRef *net_pinref_from_index (const db::Net *net, size_t index) const + virtual size_t net_subcircuit_pin_count (const net_pair &nets) const { - return attr_by_object_and_index (net, index, net->begin_pins (), net->end_pins (), m_pinref_by_net_and_index, sort_by_pin_name ()); + return nets.first->subcircuit_pin_count (); } - const db::Device *device_from_index (const db::Circuit *circuit, size_t index) const + virtual size_t net_pin_count (const net_pair &nets) const { - return attr_by_object_and_index (circuit, index, circuit->begin_devices (), circuit->end_devices (), m_device_by_circuit_and_index, sort_by_expanded_name ()); + return nets.first->pin_count (); } - const db::Pin *pin_from_index (const db::Circuit *circuit, size_t index) const + virtual size_t device_count (const circuit_pair &circuits) const { - return attr_by_object_and_index (circuit, index, circuit->begin_pins (), circuit->end_pins (), m_pin_by_circuit_and_index, sort_by_expanded_name ()); + return circuits.first->device_count (); } - const db::SubCircuit *subcircuit_from_index (const db::Circuit *circuit, size_t index) const + virtual size_t pin_count (const circuit_pair &circuits) const { - return attr_by_object_and_index (circuit, index, circuit->begin_subcircuits (), circuit->end_subcircuits (), m_subcircuit_by_circuit_and_index, sort_by_expanded_name ()); + return circuits.first->pin_count (); } - size_t circuit_index (const db::Circuit *circuit) const + virtual size_t subcircuit_count (const circuit_pair &circuits) const { - return index_from_attr (circuit, mp_netlist->begin_circuits (), mp_netlist->end_circuits (), m_circuit_index_by_object, sort_by_name ()); + return circuits.first->subcircuit_count (); } - size_t net_index (const db::Net *net) const + virtual circuit_pair parent_of (const net_pair &nets) const { - const db::Circuit *circuit = net->circuit (); - return index_from_attr (net, circuit->begin_nets (), circuit->end_nets (), m_net_index_by_object, sort_by_expanded_name ()); + return std::make_pair (nets.first->circuit (), (const db::Circuit *) 0); } - size_t device_index (const db::Device *device) const + virtual circuit_pair parent_of (const device_pair &devices) const { - const db::Circuit *circuit = device->circuit (); - return index_from_attr (device, circuit->begin_devices (), circuit->end_devices (), m_device_index_by_object, sort_by_expanded_name ()); + return std::make_pair (devices.first->circuit (), (const db::Circuit *) 0); } - size_t pin_index (const db::Pin *pin, const db::Circuit *circuit) const + virtual circuit_pair parent_of (const subcircuit_pair &subcircuits) const { - return index_from_attr (pin, circuit->begin_pins (), circuit->end_pins (), m_pin_index_by_object, sort_by_expanded_name ()); + return std::make_pair (subcircuits.first->circuit (), (const db::Circuit *) 0); } - size_t subcircuit_index (const db::SubCircuit *subcircuit) const + virtual circuit_pair circuit_from_index (size_t index) const { - const db::Circuit *circuit = subcircuit->circuit (); - return index_from_attr (subcircuit, circuit->begin_subcircuits (), circuit->end_subcircuits (), m_subcircuit_index_by_object, sort_by_expanded_name ()); + db::Netlist::const_circuit_iterator none; + return attr_by_object_and_index (std::make_pair (mp_netlist, (const db::Netlist *) 0), index, mp_netlist->begin_circuits (), mp_netlist->end_circuits (), none, none, m_circuit_by_index, sort_by_name ()); + } + + virtual net_pair net_from_index (const circuit_pair &circuits, size_t index) const + { + db::Circuit::const_net_iterator none; + return attr_by_object_and_index (circuits, index, circuits.first->begin_nets (), circuits.first->end_nets (), none, none, m_net_by_circuit_and_index, sort_by_expanded_name ()); + } + + virtual const db::Net *second_net_for (const db::Net * /*first*/) const + { + return 0; + } + + virtual net_subcircuit_pin_pair net_subcircuit_pinref_from_index (const net_pair &nets, size_t index) const + { + db::Net::const_subcircuit_pin_iterator none; + return attr_by_object_and_index (nets, index, nets.first->begin_subcircuit_pins (), nets.first->end_subcircuit_pins (), none, none, m_subcircuit_pinref_by_net_and_index, sort_by_pin_name ()); + } + + virtual net_terminal_pair net_terminalref_from_index (const net_pair &nets, size_t index) const + { + db::Net::const_terminal_iterator none; + return attr_by_object_and_index (nets, index, nets.first->begin_terminals (), nets.first->end_terminals (), none, none, m_terminalref_by_net_and_index, sort_by_terminal_id ()); + } + + virtual net_pin_pair net_pinref_from_index (const net_pair &nets, size_t index) const + { + db::Net::const_pin_iterator none; + return attr_by_object_and_index (nets, index, nets.first->begin_pins (), nets.first->end_pins (), none, none, m_pinref_by_net_and_index, sort_by_pin_name ()); + } + + virtual device_pair device_from_index (const circuit_pair &circuits, size_t index) const + { + db::Circuit::const_device_iterator none; + return attr_by_object_and_index (circuits, index, circuits.first->begin_devices (), circuits.first->end_devices (), none, none, m_device_by_circuit_and_index, sort_by_expanded_name ()); + } + + virtual pin_pair pin_from_index (const circuit_pair &circuits, size_t index) const + { + db::Circuit::const_pin_iterator none; + return attr_by_object_and_index (circuits, index, circuits.first->begin_pins (), circuits.first->end_pins (), none, none, m_pin_by_circuit_and_index, sort_by_expanded_name ()); + } + + virtual subcircuit_pair subcircuit_from_index (const circuit_pair &circuits, size_t index) const + { + db::Circuit::const_subcircuit_iterator none; + return attr_by_object_and_index (circuits, index, circuits.first->begin_subcircuits (), circuits.first->end_subcircuits (), none, none, m_subcircuit_by_circuit_and_index, sort_by_expanded_name ()); + } + + virtual size_t circuit_index (const circuit_pair &circuits) const + { + db::Netlist::const_circuit_iterator none; + return index_from_attr (circuits, mp_netlist->begin_circuits (), mp_netlist->end_circuits (), none, none, m_circuit_index_by_object, sort_by_name ()); + } + + virtual size_t net_index (const net_pair &nets) const + { + db::Circuit::const_net_iterator none; + + circuit_pair circuits = parent_of (nets); + return index_from_attr (nets, + circuits.first ? circuits.first->begin_nets () : none, circuits.first ? circuits.first->end_nets () : none, + circuits.second ? circuits.second->begin_nets () : none, circuits.second ? circuits.second->end_nets () : none, + m_net_index_by_object, sort_by_expanded_name ()); + } + + virtual size_t device_index (const device_pair &devices) const + { + db::Circuit::const_device_iterator none; + + circuit_pair circuits = parent_of (devices); + return index_from_attr (devices, + circuits.first ? circuits.first->begin_devices () : none, circuits.first ? circuits.first->end_devices () : none, + circuits.second ? circuits.second->begin_devices () : none, circuits.second ? circuits.second->end_devices () : none, + m_device_index_by_object, sort_by_expanded_name ()); + } + + virtual size_t pin_index (const pin_pair &pins, const circuit_pair &circuits) const + { + db::Circuit::const_pin_iterator none; + + return index_from_attr (pins, + circuits.first ? circuits.first->begin_pins () : none, circuits.first ? circuits.first->end_pins () : none, + circuits.second ? circuits.second->begin_pins () : none, circuits.second ? circuits.second->end_pins () : none, + m_pin_index_by_object, sort_by_expanded_name ()); + } + + virtual size_t subcircuit_index (const subcircuit_pair &subcircuits) const + { + db::Circuit::const_subcircuit_iterator none; + + circuit_pair circuits = parent_of (subcircuits); + return index_from_attr (subcircuits, + circuits.first ? circuits.first->begin_subcircuits () : none, circuits.first ? circuits.first->end_subcircuits () : none, + circuits.second ? circuits.second->begin_subcircuits () : none, circuits.second ? circuits.second->end_subcircuits () : none, + m_subcircuit_index_by_object, sort_by_expanded_name ()); } private: + typedef std::pair netlist_pair; + const db::Netlist *mp_netlist; - mutable std::map > m_circuit_by_index; - mutable std::map > m_net_by_circuit_and_index; - mutable std::map > m_subcircuit_pinref_by_net_and_index; - mutable std::map > m_terminalref_by_net_and_index; - mutable std::map > m_pinref_by_net_and_index; - mutable std::map > m_device_by_circuit_and_index; - mutable std::map > m_pin_by_circuit_and_index; - mutable std::map > m_subcircuit_by_circuit_and_index; - mutable std::map m_circuit_index_by_object; - mutable std::map m_net_index_by_object; - mutable std::map m_pin_index_by_object; - mutable std::map m_subcircuit_index_by_object; - mutable std::map m_device_index_by_object; + mutable std::map > m_circuit_by_index; + mutable std::map > m_net_by_circuit_and_index; + mutable std::map > m_subcircuit_pinref_by_net_and_index; + mutable std::map > m_terminalref_by_net_and_index; + mutable std::map > m_pinref_by_net_and_index; + mutable std::map > m_device_by_circuit_and_index; + mutable std::map > m_pin_by_circuit_and_index; + mutable std::map > m_subcircuit_by_circuit_and_index; + mutable std::map m_circuit_index_by_object; + mutable std::map m_net_index_by_object; + mutable std::map m_pin_index_by_object; + mutable std::map m_subcircuit_index_by_object; + mutable std::map m_device_index_by_object; }; // ---------------------------------------------------------------------------------- @@ -448,261 +634,261 @@ NetlistBrowserModel::make_id_circuit (size_t circuit_index) const void * NetlistBrowserModel::make_id_circuit_pin (size_t circuit_index, size_t pin_index) const { - return make_id (circuit_index, netlist ()->circuit_count (), 1, 8, pin_index); + return make_id (circuit_index, mp_indexer->circuit_count (), 1, 8, pin_index); } void * NetlistBrowserModel::make_id_circuit_pin_net (size_t circuit_index, size_t pin_index, size_t net_index) const { - const db::Circuit *circuit = circuit_from_id (make_id_circuit (circuit_index)); - return make_id (circuit_index, netlist ()->circuit_count (), 1, 8, pin_index, circuit->pin_count (), net_index + 1); + IndexedNetlistModel::circuit_pair circuits = circuits_from_id (make_id_circuit (circuit_index)); + return make_id (circuit_index, mp_indexer->circuit_count (), 1, 8, pin_index, mp_indexer->pin_count (circuits), net_index + 1); } void * NetlistBrowserModel::make_id_circuit_net (size_t circuit_index, size_t net_index) const { - return make_id (circuit_index, netlist ()->circuit_count (), 2, 8, net_index); + return make_id (circuit_index, mp_indexer->circuit_count (), 2, 8, net_index); } void * NetlistBrowserModel::make_id_circuit_net_device_terminal (size_t circuit_index, size_t net_index, size_t terminal_ref_index) const { - const db::Circuit *circuit = circuit_from_id (make_id_circuit (circuit_index)); - return make_id (circuit_index, netlist ()->circuit_count (), 2, 8, net_index, circuit->net_count (), 1, 4, terminal_ref_index); + IndexedNetlistModel::circuit_pair circuits = circuits_from_id (make_id_circuit (circuit_index)); + return make_id (circuit_index, mp_indexer->circuit_count (), 2, 8, net_index, mp_indexer->net_count (circuits), 1, 4, terminal_ref_index); } void * NetlistBrowserModel::make_id_circuit_net_device_terminal_others (size_t circuit_index, size_t net_index, size_t terminal_ref_index, size_t other_index) const { - const db::Circuit *circuit = circuit_from_id (make_id_circuit (circuit_index)); - const db::Net *net = net_from_id (make_id_circuit_net (circuit_index, net_index)); - return make_id (circuit_index, netlist ()->circuit_count (), 2, 8, net_index, circuit->net_count (), 1, 4, terminal_ref_index, net->terminal_count (), other_index + 1); + IndexedNetlistModel::circuit_pair circuits = circuits_from_id (make_id_circuit (circuit_index)); + IndexedNetlistModel::net_pair nets = nets_from_id (make_id_circuit_net (circuit_index, net_index)); + return make_id (circuit_index, mp_indexer->circuit_count (), 2, 8, net_index, mp_indexer->net_count (circuits), 1, 4, terminal_ref_index, mp_indexer->net_terminal_count (nets), other_index + 1); } void * NetlistBrowserModel::make_id_circuit_net_pin (size_t circuit_index, size_t net_index, size_t pin_index) const { - const db::Circuit *circuit = circuit_from_id (make_id_circuit (circuit_index)); - return make_id (circuit_index, netlist ()->circuit_count (), 2, 8, net_index, circuit->net_count (), 2, 4, pin_index); + IndexedNetlistModel::circuit_pair circuits = circuits_from_id (make_id_circuit (circuit_index)); + return make_id (circuit_index, mp_indexer->circuit_count (), 2, 8, net_index, mp_indexer->net_count (circuits), 2, 4, pin_index); } void * NetlistBrowserModel::make_id_circuit_net_subcircuit_pin (size_t circuit_index, size_t net_index, size_t pin_ref_index) const { - const db::Circuit *circuit = circuit_from_id (make_id_circuit (circuit_index)); - return make_id (circuit_index, netlist ()->circuit_count (), 2, 8, net_index, circuit->net_count (), 3, 4, pin_ref_index); + IndexedNetlistModel::circuit_pair circuits = circuits_from_id (make_id_circuit (circuit_index)); + return make_id (circuit_index, mp_indexer->circuit_count (), 2, 8, net_index, mp_indexer->net_count (circuits), 3, 4, pin_ref_index); } void * NetlistBrowserModel::make_id_circuit_net_subcircuit_pin_others (size_t circuit_index, size_t net_index, size_t pin_ref_index, size_t other_index) const { - const db::Circuit *circuit = circuit_from_id (make_id_circuit (circuit_index)); - const db::Net *net = net_from_id (make_id_circuit_net (circuit_index, net_index)); - return make_id (circuit_index, netlist ()->circuit_count (), 2, 8, net_index, circuit->net_count (), 3, 4, pin_ref_index, net->subcircuit_pin_count (), other_index + 1); + IndexedNetlistModel::circuit_pair circuits = circuits_from_id (make_id_circuit (circuit_index)); + IndexedNetlistModel::net_pair nets = nets_from_id (make_id_circuit_net (circuit_index, net_index)); + return make_id (circuit_index, mp_indexer->circuit_count (), 2, 8, net_index, mp_indexer->net_count (circuits), 3, 4, pin_ref_index, mp_indexer->net_subcircuit_pin_count (nets), other_index + 1); } void * NetlistBrowserModel::make_id_circuit_subcircuit (size_t circuit_index, size_t subcircuit_index) const { - return make_id (circuit_index, netlist ()->circuit_count (), 3, 8, subcircuit_index); + return make_id (circuit_index, mp_indexer->circuit_count (), 3, 8, subcircuit_index); } void * NetlistBrowserModel::make_id_circuit_subcircuit_pin (size_t circuit_index, size_t subcircuit_index, size_t pin_index) const { - const db::Circuit *circuit = circuit_from_id (make_id_circuit (circuit_index)); - return make_id (circuit_index, netlist ()->circuit_count (), 3, 8, subcircuit_index, circuit->subcircuit_count (), pin_index + 1); + IndexedNetlistModel::circuit_pair circuits = circuits_from_id (make_id_circuit (circuit_index)); + return make_id (circuit_index, mp_indexer->circuit_count (), 3, 8, subcircuit_index, mp_indexer->subcircuit_count (circuits), pin_index + 1); } void * NetlistBrowserModel::make_id_circuit_device (size_t circuit_index, size_t device_index) const { - return make_id (circuit_index, netlist ()->circuit_count (), 4, 8, device_index); + return make_id (circuit_index, mp_indexer->circuit_count (), 4, 8, device_index); } void * NetlistBrowserModel::make_id_circuit_device_terminal (size_t circuit_index, size_t device_index, size_t terminal_index) const { - const db::Circuit *circuit = circuit_from_id (make_id_circuit (circuit_index)); - return make_id (circuit_index, netlist ()->circuit_count (), 4, 8, device_index, circuit->device_count (), terminal_index + 1); + IndexedNetlistModel::circuit_pair circuits = circuits_from_id (make_id_circuit (circuit_index)); + return make_id (circuit_index, mp_indexer->circuit_count (), 4, 8, device_index, mp_indexer->device_count (circuits), terminal_index + 1); } bool NetlistBrowserModel::is_id_circuit (void *id) const { - pop (id, netlist ()->circuit_count ()); + pop (id, mp_indexer->circuit_count ()); return id == 0; } bool NetlistBrowserModel::is_id_circuit_pin (void *id) const { - const db::Circuit *circuit = circuit_from_id (id); - pop (id, netlist ()->circuit_count ()); - return (pop (id, 8) == 1 && always (pop (id, circuit->pin_count ())) && id == 0); + IndexedNetlistModel::circuit_pair circuits = circuits_from_id (id); + pop (id, mp_indexer->circuit_count ()); + return (pop (id, 8) == 1 && always (pop (id, mp_indexer->pin_count (circuits))) && id == 0); } bool NetlistBrowserModel::is_id_circuit_pin_net (void *id) const { - const db::Circuit *circuit = circuit_from_id (id); - pop (id, netlist ()->circuit_count ()); - return (pop (id, 8) == 1 && always (pop (id, circuit->pin_count ())) && id != 0); + IndexedNetlistModel::circuit_pair circuits = circuits_from_id (id); + pop (id, mp_indexer->circuit_count ()); + return (pop (id, 8) == 1 && always (pop (id, mp_indexer->pin_count (circuits))) && id != 0); } bool NetlistBrowserModel::is_id_circuit_net (void *id) const { - const db::Circuit *circuit = circuit_from_id (id); - pop (id, netlist ()->circuit_count ()); - return (pop (id, 8) == 2 && always (pop (id, circuit->net_count ())) && id == 0); + IndexedNetlistModel::circuit_pair circuits = circuits_from_id (id); + pop (id, mp_indexer->circuit_count ()); + return (pop (id, 8) == 2 && always (pop (id, mp_indexer->net_count (circuits))) && id == 0); } bool NetlistBrowserModel::is_id_circuit_net_device_terminal (void *id) const { - const db::Circuit *circuit = circuit_from_id (id); - const db::Net *net = net_from_id (id); - pop (id, netlist ()->circuit_count ()); - return (pop (id, 8) == 2 && always (pop (id, circuit->net_count ())) && pop (id, 4) == 1 && always (pop (id, net->terminal_count ())) && id == 0); + IndexedNetlistModel::circuit_pair circuits = circuits_from_id (id); + IndexedNetlistModel::net_pair nets = nets_from_id (id); + pop (id, mp_indexer->circuit_count ()); + return (pop (id, 8) == 2 && always (pop (id, mp_indexer->net_count (circuits))) && pop (id, 4) == 1 && always (pop (id, mp_indexer->net_terminal_count (nets))) && id == 0); } bool NetlistBrowserModel::is_id_circuit_net_device_terminal_others (void *id) const { - const db::Circuit *circuit = circuit_from_id (id); - const db::Net *net = net_from_id (id); - pop (id, netlist ()->circuit_count ()); - return (pop (id, 8) == 2 && always (pop (id, circuit->net_count ())) && pop (id, 4) == 1 && always (pop (id, net->terminal_count ())) && id != 0); + IndexedNetlistModel::circuit_pair circuits = circuits_from_id (id); + IndexedNetlistModel::net_pair nets = nets_from_id (id); + pop (id, mp_indexer->circuit_count ()); + return (pop (id, 8) == 2 && always (pop (id, mp_indexer->net_count (circuits))) && pop (id, 4) == 1 && always (pop (id, mp_indexer->net_terminal_count (nets))) && id != 0); } bool NetlistBrowserModel::is_id_circuit_net_pin (void *id) const { - const db::Circuit *circuit = circuit_from_id (id); - pop (id, netlist ()->circuit_count ()); - return (pop (id, 8) == 2 && always (pop (id, circuit->net_count ())) && pop (id, 4) == 2); + IndexedNetlistModel::circuit_pair circuits = circuits_from_id (id); + pop (id, mp_indexer->circuit_count ()); + return (pop (id, 8) == 2 && always (pop (id, mp_indexer->net_count (circuits))) && pop (id, 4) == 2); } bool NetlistBrowserModel::is_id_circuit_net_subcircuit_pin (void *id) const { - const db::Circuit *circuit = circuit_from_id (id); - const db::Net *net = net_from_id (id); - pop (id, netlist ()->circuit_count ()); - return (pop (id, 8) == 2 && always (pop (id, circuit->net_count ())) && pop (id, 4) == 3 && always (pop (id, net->subcircuit_pin_count ())) && id == 0); + IndexedNetlistModel::circuit_pair circuits = circuits_from_id (id); + IndexedNetlistModel::net_pair nets = nets_from_id (id); + pop (id, mp_indexer->circuit_count ()); + return (pop (id, 8) == 2 && always (pop (id, mp_indexer->net_count (circuits))) && pop (id, 4) == 3 && always (pop (id, mp_indexer->net_subcircuit_pin_count (nets))) && id == 0); } bool NetlistBrowserModel::is_id_circuit_net_subcircuit_pin_others (void *id) const { - const db::Circuit *circuit = circuit_from_id (id); - const db::Net *net = net_from_id (id); - pop (id, netlist ()->circuit_count ()); - return (pop (id, 8) == 2 && always (pop (id, circuit->net_count ())) && pop (id, 4) == 3 && always (pop (id, net->subcircuit_pin_count ())) && id != 0); + IndexedNetlistModel::circuit_pair circuits = circuits_from_id (id); + IndexedNetlistModel::net_pair nets = nets_from_id (id); + pop (id, mp_indexer->circuit_count ()); + return (pop (id, 8) == 2 && always (pop (id, mp_indexer->net_count (circuits))) && pop (id, 4) == 3 && always (pop (id, mp_indexer->net_subcircuit_pin_count (nets))) && id != 0); } bool NetlistBrowserModel::is_id_circuit_subcircuit (void *id) const { - const db::Circuit *circuit = circuit_from_id (id); - pop (id, netlist ()->circuit_count ()); - return (pop (id, 8) == 3 && always (pop (id, circuit->subcircuit_count ())) && id == 0); + IndexedNetlistModel::circuit_pair circuits = circuits_from_id (id); + pop (id, mp_indexer->circuit_count ()); + return (pop (id, 8) == 3 && always (pop (id, mp_indexer->subcircuit_count (circuits))) && id == 0); } bool NetlistBrowserModel::is_id_circuit_subcircuit_pin (void *id) const { - const db::Circuit *circuit = circuit_from_id (id); - pop (id, netlist ()->circuit_count ()); - return (pop (id, 8) == 3 && always (pop (id, circuit->subcircuit_count ())) && id != 0); + IndexedNetlistModel::circuit_pair circuits = circuits_from_id (id); + pop (id, mp_indexer->circuit_count ()); + return (pop (id, 8) == 3 && always (pop (id, mp_indexer->subcircuit_count (circuits))) && id != 0); } bool NetlistBrowserModel::is_id_circuit_device (void *id) const { - const db::Circuit *circuit = circuit_from_id (id); - pop (id, netlist ()->circuit_count ()); - return (pop (id, 8) == 4 && always (pop (id, circuit->device_count ())) && id == 0); + IndexedNetlistModel::circuit_pair circuits = circuits_from_id (id); + pop (id, mp_indexer->circuit_count ()); + return (pop (id, 8) == 4 && always (pop (id, mp_indexer->device_count (circuits))) && id == 0); } bool NetlistBrowserModel::is_id_circuit_device_terminal (void *id) const { - const db::Circuit *circuit = circuit_from_id (id); - pop (id, netlist ()->circuit_count ()); - return (pop (id, 8) == 4 && always (pop (id, circuit->device_count ())) && id != 0); + IndexedNetlistModel::circuit_pair circuits = circuits_from_id (id); + pop (id, mp_indexer->circuit_count ()); + return (pop (id, 8) == 4 && always (pop (id, mp_indexer->device_count (circuits))) && id != 0); } size_t NetlistBrowserModel::circuit_index_from_id (void *id) const { - return pop (id, netlist ()->circuit_count ()); + return pop (id, mp_indexer->circuit_count ()); } size_t NetlistBrowserModel::circuit_pin_index_from_id (void *id) const { - const db::Circuit *circuit = circuit_from_id (id); - pop (id, netlist ()->circuit_count ()); + IndexedNetlistModel::circuit_pair circuits = circuits_from_id (id); + pop (id, mp_indexer->circuit_count ()); pop (id, 8); - return pop (id, circuit->pin_count ()); + return pop (id, mp_indexer->pin_count (circuits)); } size_t NetlistBrowserModel::circuit_device_index_from_id (void *id) const { - const db::Circuit *circuit = circuit_from_id (id); - pop (id, netlist ()->circuit_count ()); + IndexedNetlistModel::circuit_pair circuits = circuits_from_id (id); + pop (id, mp_indexer->circuit_count ()); pop (id, 8); - return pop (id, circuit->device_count ()); + return pop (id, mp_indexer->device_count (circuits)); } size_t NetlistBrowserModel::circuit_device_terminal_index_from_id (void *id) const { - const db::Circuit *circuit = circuit_from_id (id); - pop (id, netlist ()->circuit_count ()); + IndexedNetlistModel::circuit_pair circuits = circuits_from_id (id); + pop (id, mp_indexer->circuit_count ()); pop (id, 8); - pop (id, circuit->device_count ()); + pop (id, mp_indexer->device_count (circuits)); return reinterpret_cast (id) - 1; } size_t NetlistBrowserModel::circuit_subcircuit_index_from_id (void *id) const { - const db::Circuit *circuit = circuit_from_id (id); - pop (id, netlist ()->circuit_count ()); + IndexedNetlistModel::circuit_pair circuits = circuits_from_id (id); + pop (id, mp_indexer->circuit_count ()); pop (id, 8); - return pop (id, circuit->subcircuit_count ()); + return pop (id, mp_indexer->subcircuit_count (circuits)); } size_t NetlistBrowserModel::circuit_subcircuit_pin_index_from_id (void *id) const { - const db::Circuit *circuit = circuit_from_id (id); - pop (id, netlist ()->circuit_count ()); + IndexedNetlistModel::circuit_pair circuits = circuits_from_id (id); + pop (id, mp_indexer->circuit_count ()); pop (id, 8); - pop (id, circuit->subcircuit_count ()); + pop (id, mp_indexer->subcircuit_count (circuits)); return reinterpret_cast (id) - 1; } size_t NetlistBrowserModel::circuit_net_index_from_id (void *id) const { - const db::Circuit *circuit = circuit_from_id (id); - pop (id, netlist ()->circuit_count ()); + IndexedNetlistModel::circuit_pair circuits = circuits_from_id (id); + pop (id, mp_indexer->circuit_count ()); pop (id, 8); - return pop (id, circuit->net_count ()); + return pop (id, mp_indexer->net_count (circuits)); } size_t NetlistBrowserModel::circuit_net_pin_index_from_id (void *id) const { - const db::Circuit *circuit = circuit_from_id (id); - pop (id, netlist ()->circuit_count ()); + IndexedNetlistModel::circuit_pair circuits = circuits_from_id (id); + pop (id, mp_indexer->circuit_count ()); pop (id, 8); - pop (id, circuit->net_count ()); + pop (id, mp_indexer->net_count (circuits)); pop (id, 4); return reinterpret_cast (id); } @@ -710,50 +896,50 @@ NetlistBrowserModel::circuit_net_pin_index_from_id (void *id) const size_t NetlistBrowserModel::circuit_net_subcircuit_pin_index_from_id (void *id) const { - const db::Circuit *circuit = circuit_from_id (id); - const db::Net *net = net_from_id (id); - pop (id, netlist ()->circuit_count ()); + IndexedNetlistModel::circuit_pair circuits = circuits_from_id (id); + IndexedNetlistModel::net_pair nets = nets_from_id (id); + pop (id, mp_indexer->circuit_count ()); pop (id, 8); - pop (id, circuit->net_count ()); + pop (id, mp_indexer->net_count (circuits)); pop (id, 4); - return pop (id, net->subcircuit_pin_count ()); + return pop (id, mp_indexer->net_subcircuit_pin_count (nets)); } size_t NetlistBrowserModel::circuit_net_subcircuit_pin_other_index_from_id (void *id) const { - const db::Circuit *circuit = circuit_from_id (id); - const db::Net *net = net_from_id (id); - pop (id, netlist ()->circuit_count ()); + IndexedNetlistModel::circuit_pair circuits = circuits_from_id (id); + IndexedNetlistModel::net_pair nets = nets_from_id (id); + pop (id, mp_indexer->circuit_count ()); pop (id, 8); - pop (id, circuit->net_count ()); + pop (id, mp_indexer->net_count (circuits)); pop (id, 4); - pop (id, net->subcircuit_pin_count ()); + pop (id, mp_indexer->net_subcircuit_pin_count (nets)); return reinterpret_cast (id) - 1; } size_t NetlistBrowserModel::circuit_net_device_terminal_index_from_id (void *id) const { - const db::Circuit *circuit = circuit_from_id (id); - const db::Net *net = net_from_id (id); - pop (id, netlist ()->circuit_count ()); + IndexedNetlistModel::circuit_pair circuits = circuits_from_id (id); + IndexedNetlistModel::net_pair nets = nets_from_id (id); + pop (id, mp_indexer->circuit_count ()); pop (id, 8); - pop (id, circuit->net_count ()); + pop (id, mp_indexer->net_count (circuits)); pop (id, 4); - return pop (id, net->terminal_count ()); + return pop (id, mp_indexer->net_terminal_count (nets)); } size_t NetlistBrowserModel::circuit_net_device_terminal_other_index_from_id (void *id) const { - const db::Circuit *circuit = circuit_from_id (id); - const db::Net *net = net_from_id (id); - pop (id, netlist ()->circuit_count ()); + IndexedNetlistModel::circuit_pair circuits = circuits_from_id (id); + IndexedNetlistModel::net_pair nets = nets_from_id (id); + pop (id, mp_indexer->circuit_count ()); pop (id, 8); - pop (id, circuit->net_count ()); + pop (id, mp_indexer->net_count (circuits)); pop (id, 4); - pop (id, net->terminal_count ()); + pop (id, mp_indexer->net_terminal_count (nets)); return reinterpret_cast (id) - 1; } @@ -782,59 +968,70 @@ NetlistBrowserModel::data (const QModelIndex &index, int role) const } } -QString -NetlistBrowserModel::make_link_to (const db::Net *net) const +template +static std::string str_from_expanded_name (const Obj *obj) { - if (! net) { - return QString (); + if (obj) { + return obj->expanded_name (); } else { - void *id = make_id_circuit_net (mp_indexer->circuit_index (net->circuit ()), mp_indexer->net_index (net)); - return tl::to_qstring (tl::sprintf ("%s", tl::to_string (reinterpret_cast (id)), net->expanded_name ())); + return std::string (); } } -QString -NetlistBrowserModel::make_link_to (const db::Device *device) const +template +static std::string str_from_name (const Obj *obj) { - if (! device) { - return QString (); + if (obj) { + return obj->name (); } else { - void *id = make_id_circuit_device (mp_indexer->circuit_index (device->circuit ()), mp_indexer->device_index (device)); - return tl::to_qstring (tl::sprintf ("%s", tl::to_string (reinterpret_cast (id)), device->expanded_name ())); + return std::string (); } } -QString -NetlistBrowserModel::make_link_to (const db::Pin *pin, const db::Circuit *circuit) const +template +static std::string str_from_expanded_names (const std::pair &objs, bool is_single) { - if (! pin) { - return QString (); - } else { - void *id = make_id_circuit_pin (mp_indexer->circuit_index (circuit), mp_indexer->pin_index (pin, circuit)); - return tl::to_qstring (tl::sprintf ("%s", tl::to_string (reinterpret_cast (id)), pin->expanded_name ())); + std::string s; + + if (objs.first) { + s += objs.first->expanded_name (); + } else if (! is_single) { + s += "-"; } + + if (! is_single) { + s += "/"; + if (objs.second) { + s += objs.second->expanded_name (); + } else { + s += "-"; + } + } + + return s; } -QString -NetlistBrowserModel::make_link_to (const db::Circuit *circuit) const +template +static std::string str_from_names (const std::pair &objs, bool is_single) { - if (! circuit) { - return QString (); - } else { - void *id = make_id_circuit (mp_indexer->circuit_index (circuit)); - return tl::to_qstring (tl::sprintf ("%s", tl::to_string (reinterpret_cast (id)), circuit->name ())); - } -} + std::string s; -QString -NetlistBrowserModel::make_link_to (const db::SubCircuit *sub_circuit) const -{ - if (! sub_circuit) { - return QString (); - } else { - void *id = make_id_circuit_subcircuit (mp_indexer->circuit_index (sub_circuit->circuit ()), mp_indexer->subcircuit_index (sub_circuit)); - return tl::to_qstring (tl::sprintf ("%s", tl::to_string (reinterpret_cast (id)), sub_circuit->expanded_name ())); + if (objs.first) { + s += objs.first->name (); + } else if (! is_single) { + s += "-"; } + + if (! is_single) { + s += "/"; + if (objs.second) { + s += objs.second->name (); + } else { + s += "-"; + } + } + + return s; } static @@ -865,6 +1062,223 @@ std::string device_string (const db::Device *device) return s; } +static +std::string devices_string (const std::pair &devices, bool is_single) +{ + if (devices.first || devices.second) { + + std::string s; + if (devices.first && devices.first->device_class ()) { + s += devices.first->device_class ()->name (); + } else if (! is_single) { + s += "-"; + } + + if (! is_single) { + s += "/"; + if (devices.second && devices.second->device_class ()) { + s += devices.second->device_class ()->name (); + } else { + s += "-"; + } + } + + return s; + + } else { + return std::string (); + } +} + +QString +NetlistBrowserModel::make_link_to (const std::pair &nets) const +{ + if (! nets.first && ! nets.second) { + return QString (); + } else { + void *id = make_id_circuit_net (mp_indexer->circuit_index (mp_indexer->parent_of (nets)), mp_indexer->net_index (nets)); + return tl::to_qstring (tl::sprintf ("%s", tl::to_string (reinterpret_cast (id)), str_from_expanded_names (nets, mp_indexer->is_single ()))); + } +} + +QString +NetlistBrowserModel::make_link_to (const std::pair &devices) const +{ + if (! devices.first && ! devices.second) { + return QString (); + } else { + void *id = make_id_circuit_device (mp_indexer->circuit_index (mp_indexer->parent_of (devices)), mp_indexer->device_index (devices)); + return tl::to_qstring (tl::sprintf ("%s", tl::to_string (reinterpret_cast (id)), str_from_expanded_names (devices, mp_indexer->is_single ()))); + } +} + +QString +NetlistBrowserModel::make_link_to (const std::pair &pins, const std::pair &circuits) const +{ + if (! pins.first && ! pins.second) { + return QString (); + } else { + void *id = make_id_circuit_pin (mp_indexer->circuit_index (circuits), mp_indexer->pin_index (pins, circuits)); + return tl::to_qstring (tl::sprintf ("%s", tl::to_string (reinterpret_cast (id)), str_from_expanded_names (pins, mp_indexer->is_single ()))); + } +} + +QString +NetlistBrowserModel::make_link_to (const std::pair &circuits) const +{ + if (! circuits.first && ! circuits.second) { + return QString (); + } else { + void *id = make_id_circuit (mp_indexer->circuit_index (circuits)); + return tl::to_qstring (tl::sprintf ("%s", tl::to_string (reinterpret_cast (id)), str_from_names (circuits, mp_indexer->is_single ()))); + } +} + +QString +NetlistBrowserModel::make_link_to (const std::pair &subcircuits) const +{ + if (! subcircuits.first && ! subcircuits.second) { + return QString (); + } else { + void *id = make_id_circuit_subcircuit (mp_indexer->circuit_index (mp_indexer->parent_of (subcircuits)), mp_indexer->subcircuit_index (subcircuits)); + return tl::to_qstring (tl::sprintf ("%s", tl::to_string (reinterpret_cast (id)), str_from_expanded_names (subcircuits, mp_indexer->is_single ()))); + } +} + +static +IndexedNetlistModel::circuit_pair circuit_refs_from_subcircuits (const IndexedNetlistModel::subcircuit_pair &subcircuits) +{ + const db::Circuit *circuit1 = 0, *circuit2 = 0; + if (subcircuits.first) { + circuit1 = subcircuits.first->circuit_ref (); + } + if (subcircuits.second) { + circuit2 = subcircuits.second->circuit_ref (); + } + return std::make_pair (circuit1, circuit2); +} + +static +IndexedNetlistModel::subcircuit_pair subcircuits_from_pinrefs (const IndexedNetlistModel::net_subcircuit_pin_pair &pinrefs) +{ + const db::SubCircuit *subcircuit1 = 0, *subcircuit2 = 0; + if (pinrefs.first) { + subcircuit1 = pinrefs.first->subcircuit (); + } + if (pinrefs.second) { + subcircuit2 = pinrefs.second->subcircuit (); + } + + return std::make_pair (subcircuit1, subcircuit2); +} + +static +IndexedNetlistModel::device_pair devices_from_termrefs (const IndexedNetlistModel::net_terminal_pair &termrefs) +{ + const db::Device *device1 = 0, *device2 = 0; + if (termrefs.first) { + device1 = termrefs.first->device (); + } + if (termrefs.second) { + device2 = termrefs.second->device (); + } + + return std::make_pair (device1, device2); +} + +static +IndexedNetlistModel::pin_pair pins_from_pinrefs (const IndexedNetlistModel::net_subcircuit_pin_pair &pinrefs) +{ + const db::Pin *pin1 = 0, *pin2 = 0; + if (pinrefs.first) { + pin1 = pinrefs.first->pin (); + } + if (pinrefs.second) { + pin2 = pinrefs.second->pin (); + } + + return std::make_pair (pin1, pin2); +} + +static +IndexedNetlistModel::pin_pair pins_from_pinrefs (const IndexedNetlistModel::net_pin_pair &pinrefs) +{ + const db::Pin *pin1 = 0, *pin2 = 0; + if (pinrefs.first) { + pin1 = pinrefs.first->pin (); + } + if (pinrefs.second) { + pin2 = pinrefs.second->pin (); + } + + 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) +{ + const db::Net *net1 = 0, *net2 = 0; + if (pins.first && circuits.first) { + net1 = circuits.first->net_for_pin (pins.first->id ()); + } + if (pins.second && circuits.second) { + net2 = circuits.second->net_for_pin (pins.second->id ()); + } + + return std::make_pair (net1, net2); +} + +static std::pair device_classes_from_devices (const IndexedNetlistModel::device_pair &devices) +{ + return std::make_pair (devices.first ? devices.first->device_class () : 0, devices.second ? devices.second->device_class () : 0); +} + +static std::pair terminal_defs_from_terminal_refs (const IndexedNetlistModel::net_terminal_pair &termrefs) +{ + return std::make_pair (termrefs.first ? termrefs.first->terminal_def () : 0, termrefs.second ? termrefs.second->terminal_def () : 0); +} + +static std::pair terminal_defs_from_device_classes (const std::pair &device_classes, size_t terminal_id) +{ + const db::DeviceTerminalDefinition *td1 = 0, *td2 = 0; + if (device_classes.first && device_classes.first->terminal_definitions ().size () > terminal_id) { + td1 = &device_classes.first->terminal_definitions () [terminal_id]; + } + if (device_classes.second && device_classes.second->terminal_definitions ().size () > terminal_id) { + td2 = &device_classes.second->terminal_definitions () [terminal_id]; + } + return std::make_pair (td1, td2); +} + +static +IndexedNetlistModel::net_pair nets_from_device_terminals (const IndexedNetlistModel::device_pair &devices, const std::pair &termdefs) +{ + const db::Net *net1 = 0, *net2 = 0; + if (termdefs.first && devices.first) { + net1 = devices.first->net_for_terminal (termdefs.first->id ()); + } + if (termdefs.second && devices.second) { + net2 = devices.second->net_for_terminal (termdefs.second->id ()); + } + + return std::make_pair (net1, net2); +} + + QString NetlistBrowserModel::text (const QModelIndex &index) const { @@ -874,136 +1288,147 @@ NetlistBrowserModel::text (const QModelIndex &index) const // circuit: header column = name, other columns empty if (index.column () == 0) { - const db::Circuit *circuit = circuit_from_id (id); - if (circuit) { - return tl::to_qstring (circuit->name ()); + IndexedNetlistModel::circuit_pair circuits = circuits_from_id (id); + if (circuits.first) { + return tl::to_qstring (circuits.first->name ()); } } + // TODO: in case of compare use different scheme } else if (is_id_circuit_pin (id)) { // circuit/pin: header column = pin name, other columns pin name - const db::Pin *pin = pin_from_id (id); - if (pin) { - return tl::to_qstring (pin->expanded_name ()); + IndexedNetlistModel::pin_pair pins = pins_from_id (id); + if (pins.first) { + return tl::to_qstring (pins.first->expanded_name ()); } // TODO: in case of compare, column 1 is name(a):name(b), 2 is name(a) and 3 is name(b) } else if (is_id_circuit_pin_net (id)) { // circuit/pin/net: header column = name, second column link to net - const db::Circuit *circuit = circuit_from_id (id); - const db::Pin *pin = pin_from_id (id); - if (pin) { - const db::Net *net = circuit->net_for_pin (pin->id ()); - if (net) { - if (index.column () == 0) { - return tl::to_qstring (net->expanded_name ()); - } else { - return make_link_to (net); - } - } + IndexedNetlistModel::circuit_pair circuits = circuits_from_id (id); + IndexedNetlistModel::pin_pair pins = pins_from_id (id); + IndexedNetlistModel::net_pair nets = nets_from_circuit_pins (circuits, pins); + + if (index.column () == 0) { + return tl::to_qstring (str_from_expanded_names (nets, mp_indexer->is_single ())); + } else { + return make_link_to (nets); } // TODO: in case of compare, column 1 is name(a):name(b), 2 is link name(a) and 3 is link name(b) } else if (is_id_circuit_device (id)) { // circuit/device: header column = class + parameters, second column device name - const db::Device *device = device_from_id (id); - if (device && device->device_class ()) { + IndexedNetlistModel::device_pair devices = devices_from_id (id); + + if (mp_indexer->is_single ()) { if (index.column () == 0) { - return tl::to_qstring (device_string (device)); - } else { - return tl::to_qstring (device->expanded_name ()); + return tl::to_qstring (device_string (devices.first)); + } else if (index.column () == 1) { + return tl::to_qstring (str_from_expanded_name (devices.first)); + } + + } else { + + if (index.column () == 0) { + return tl::to_qstring (devices_string (devices, mp_indexer->is_single ())); + } else if (index.column () == 1) { + return tl::to_qstring (str_from_expanded_name (devices.first) + " - " + device_string (devices.first)); + } else if (index.column () == 2) { + return tl::to_qstring (str_from_expanded_name (devices.second) + " - " + device_string (devices.second)); } } - // TODO: in case of compare, column 1 is name(a):name(b) [param], 2 is name(a) and 3 is name(b) } else if (is_id_circuit_device_terminal (id)) { // circuit/device/terminal: header column = terminal name, second column link to net - const db::Device *device = device_from_id (id); - if (device && device->device_class ()) { - size_t terminal = circuit_device_terminal_index_from_id (id); - if (device->device_class ()->terminal_definitions ().size () > terminal) { - const db::DeviceTerminalDefinition &td = device->device_class ()->terminal_definitions () [terminal]; - if (index.column () == 0) { - return tl::to_qstring (td.name ()); - } else { - return make_link_to (device->net_for_terminal (td.id ())); - } - } + IndexedNetlistModel::device_pair devices = devices_from_id (id); + size_t terminal = circuit_device_terminal_index_from_id (id); + + std::pair device_classes = device_classes_from_devices (devices); + std::pair termdefs = terminal_defs_from_device_classes (device_classes, terminal); + + if (index.column () == 0) { + + return tl::to_qstring (str_from_names (termdefs, mp_indexer->is_single ())); + + } else { + + IndexedNetlistModel::net_pair nets = nets_from_device_terminals (devices, termdefs); + return make_link_to (nets); + } // TODO: in case of compare, column 1 is terminal, 2 is linke net(a) and 3 is link net(b) } else if (is_id_circuit_subcircuit (id)) { // circuit/subcircuit: header column = circuit name, second column subcircuit name - const db::SubCircuit *subcircuit = subcircuit_from_id (id); - if (subcircuit) { - if (index.column () == 0) { - return make_link_to (subcircuit->circuit_ref ()); - } else { - return tl::to_qstring (subcircuit->expanded_name ()); - } + IndexedNetlistModel::subcircuit_pair subcircuits = subcircuits_from_id (id); + IndexedNetlistModel::circuit_pair circuit_refs = circuit_refs_from_subcircuits (subcircuits); + if (index.column () == 0) { + return make_link_to (circuit_refs); + } else { + return tl::to_qstring (str_from_expanded_names (subcircuits, mp_indexer->is_single ())); } // TODO: in case of compare, column 1 is circuit name(a):circuit name(b), 2 is subcircuit name(a) and 3 is subcircuit name(b) } else if (is_id_circuit_subcircuit_pin (id)) { // circuit/pin: header column = pin name, other columns net name - const db::SubCircuit *subcircuit = subcircuit_from_id (id); - if (subcircuit && subcircuit->circuit () && subcircuit->circuit_ref ()) { - const db::Pin *pin = pin_from_id (id); - if (pin) { - if (index.column () == 0) { - return make_link_to (pin, subcircuit->circuit_ref ()); - } else { - return make_link_to (subcircuit->net_for_pin (pin->id ())); - } - } + IndexedNetlistModel::subcircuit_pair subcircuits = subcircuits_from_id (id); + IndexedNetlistModel::circuit_pair circuit_refs = circuit_refs_from_subcircuits (subcircuits); + IndexedNetlistModel::pin_pair pins = pins_from_id (id); + + if (index.column () == 0) { + return make_link_to (pins, circuit_refs); + } else { + return make_link_to (nets_from_subcircuit_pins (subcircuits, pins)); } // TODO: in case of compare, column 1 is name(a):name(b), 2 is link net(a) and 3 is link net(b) } else if (is_id_circuit_net (id)) { // circuit/net: header column = node count, second column net name - const db::Net *net = net_from_id (id); - if (net) { - if (index.column () == 0) { - return tl::to_qstring (net->expanded_name ()); - } else { - return tl::to_qstring (net->expanded_name () + " (" + tl::to_string (net->pin_count () + net->terminal_count () + net->subcircuit_pin_count ()) + ")"); - } + IndexedNetlistModel::net_pair nets = nets_from_id (id); + if (index.column () == 0) { + return tl::to_qstring (str_from_expanded_names (nets, mp_indexer->is_single ())); + } else if (index.column () == 1 && nets.first) { + return tl::to_qstring (nets.first->expanded_name () + " (" + tl::to_string (nets.first->pin_count () + nets.first->terminal_count () + nets.first->subcircuit_pin_count ()) + ")"); + } else if (index.column () == 2 && nets.second) { + return tl::to_qstring (nets.second->expanded_name () + " (" + tl::to_string (nets.second->pin_count () + nets.second->terminal_count () + nets.second->subcircuit_pin_count ()) + ")"); } - // TODO: in case of compare, column 1 is name(a):name(b), 2 is name(a)(size(a)) and 3 is name(b)(size(b)) } else if (is_id_circuit_net_pin (id)) { // circuit/net/pin: header column = pin name, second column empty (for now) - const db::NetPinRef *ref = net_pinref_from_id (id); - if (ref && ref->pin ()) { - if (index.column () == 0) { - return make_link_to (ref->pin (), circuit_from_id (id)); - } - // TODO: in case of compare use second and third column + IndexedNetlistModel::net_pin_pair pinrefs = net_pinrefs_from_id (id); + IndexedNetlistModel::circuit_pair circuits = circuits_from_id (id); + if (index.column () == 0) { + + return make_link_to (pins_from_pinrefs (pinrefs), circuits); + } + // TODO: in case of compare use second and third column } else if (is_id_circuit_net_subcircuit_pin (id)) { - // circuit/net/subcircuit pin: header column = pin name - circuit name, second column link to subcircuit - const db::NetSubcircuitPinRef *ref = net_subcircuit_pinref_from_id (id); - if (ref && ref->pin () && ref->subcircuit ()) { - const db::Circuit *circuit = ref->subcircuit ()->circuit_ref (); - if (circuit) { - if (index.column () == 0) { - return make_link_to (ref->pin (), circuit) + tl::to_qstring (" - ") + make_link_to (circuit); - } else { - return make_link_to (ref->subcircuit ()); - } - } + // circuit/net/pin: header column = pin name, second column empty (for now) + IndexedNetlistModel::net_subcircuit_pin_pair pinrefs = net_subcircuit_pinrefs_from_id (id); + IndexedNetlistModel::subcircuit_pair subcircuits = subcircuits_from_pinrefs (pinrefs); + IndexedNetlistModel::circuit_pair circuit_refs = circuit_refs_from_subcircuits (subcircuits); + + if (index.column () == 0) { + + return make_link_to (pins_from_pinrefs (pinrefs), circuit_refs) + tl::to_qstring (" - ") + make_link_to (circuit_refs); + + } else if (index.column () == 1) { + + return make_link_to (subcircuits_from_pinrefs (pinrefs)); + } // TODO: in case of compare, column 1 is pin link(a):pin link(b) - circuit link(a):circuit link(b), // columns 2 is subcircuit link(a), columns (3) is subcircuit link(b) @@ -1011,53 +1436,107 @@ NetlistBrowserModel::text (const QModelIndex &index) const } else if (is_id_circuit_net_subcircuit_pin_others (id)) { // circuit/net/device terminal/more: header column = pin name, second column = net link - const db::NetSubcircuitPinRef *ref = net_subcircuit_pinref_from_id (id); + IndexedNetlistModel::net_subcircuit_pin_pair pinrefs = net_subcircuit_pinrefs_from_id (id); + IndexedNetlistModel::subcircuit_pair subcircuits = subcircuits_from_pinrefs (pinrefs); size_t other_index = circuit_net_subcircuit_pin_other_index_from_id (id); - if (ref && ref->pin () && ref->subcircuit ()) { - const db::Circuit *circuit = ref->subcircuit ()->circuit_ref (); - if (circuit) { - const db::Pin *pin = mp_indexer->pin_from_index (circuit, other_index); - if (index.column () == 0) { - return make_link_to (pin, circuit); - } else { - return make_link_to (ref->subcircuit ()->net_for_pin (pin->id ())); - } - } + IndexedNetlistModel::circuit_pair circuit_refs = circuit_refs_from_subcircuits (subcircuits); + IndexedNetlistModel::pin_pair pins = mp_indexer->pin_from_index (circuit_refs, other_index); + + if (index.column () == 0) { + return make_link_to (pins, circuit_refs); + } else { + return make_link_to (nets_from_subcircuit_pins (subcircuits, pins)); } + // TODO: columns 2 and 3 } else if (is_id_circuit_net_device_terminal (id)) { // circuit/net/device terminal: header column = terminal and device string, second column = device name - const db::NetTerminalRef *ref = net_terminalref_from_id (id); - if (ref && ref->terminal_def ()) { - if (index.column () == 0) { - return tl::to_qstring (ref->terminal_def ()->name () + " - " + device_string (ref->device ())); + IndexedNetlistModel::net_terminal_pair refs = net_terminalrefs_from_id (id); + IndexedNetlistModel::device_pair devices = devices_from_termrefs (refs); + + if (index.column () == 0) { + + std::pair termdefs = terminal_defs_from_terminal_refs (refs); + + if (mp_indexer->is_single ()) { + return tl::to_qstring (str_from_name (termdefs.first) + " - " + device_string (devices.first)); } else { - return make_link_to (ref->device ()); + return tl::to_qstring (str_from_names (termdefs, mp_indexer->is_single ()) + " - " + devices_string (devices, mp_indexer->is_single ())); } + + } else { + return make_link_to (devices); } + // TODO: columns 2 and 3 } else if (is_id_circuit_net_device_terminal_others (id)) { // circuit/net/device terminal/more: header column = terminal name, second column = net link - const db::NetTerminalRef *ref = net_terminalref_from_id (id); + IndexedNetlistModel::net_terminal_pair refs = net_terminalrefs_from_id (id); size_t other_index = circuit_net_device_terminal_other_index_from_id (id); - if (ref && ref->device_class () && ref->device_class ()->terminal_definitions ().size () > other_index) { - const db::DeviceTerminalDefinition &def = ref->device_class ()->terminal_definitions ()[other_index]; - if (index.column () == 0) { - return tl::to_qstring (def.name ()); - } else { - return make_link_to (ref->device ()->net_for_terminal (def.id ())); - } + IndexedNetlistModel::device_pair devices = devices_from_termrefs (refs); + std::pair device_classes = device_classes_from_devices (devices); + std::pair termdefs = terminal_defs_from_device_classes (device_classes, other_index); + + if (index.column () == 0) { + + return tl::to_qstring (str_from_names (termdefs, mp_indexer->is_single ())); + + } else { + + IndexedNetlistModel::net_pair nets = nets_from_device_terminals (devices, termdefs); + return make_link_to (nets); + } + // TODO: other columns } return QString (); } +static std::string combine_search_strings (const std::string &s1, const std::string &s2) +{ + if (s1.empty ()) { + return s2; + } else if (s2.empty ()) { + return s1; + } else { + return s1 + "|" + s2; + } +} + +template +static std::string search_string_from_expanded_names (const std::pair &objs) +{ + if (objs.first && objs.second) { + return combine_search_strings (objs.first->expanded_name (), objs.second->expanded_name ()); + } else if (objs.first) { + return objs.first->expanded_name (); + } else if (objs.second) { + return objs.second->expanded_name (); + } else { + return std::string (); + } +} + +template +static std::string search_string_from_names (const std::pair &objs) +{ + if (objs.first && objs.second) { + return combine_search_strings (objs.first->name (), objs.second->name ()); + } else if (objs.first) { + return objs.first->name (); + } else if (objs.second) { + return objs.second->name (); + } else { + return std::string (); + } +} + QString NetlistBrowserModel::search_text (const QModelIndex &index) const { @@ -1065,142 +1544,102 @@ NetlistBrowserModel::search_text (const QModelIndex &index) const if (is_id_circuit (id)) { - const db::Circuit *circuit = circuit_from_id (id); - if (circuit) { - return tl::to_qstring (circuit->name ()); - } - // TODO: in case of compare, use circuit_name(a)|circuit_name(b) + return tl::to_qstring (search_string_from_names (circuits_from_id (id))); } else if (is_id_circuit_pin (id)) { - const db::Pin *pin = pin_from_id (id); - if (pin) { - return tl::to_qstring (pin->expanded_name ()); - } - // TODO: in case of compare, use pin_name(a)|pin_name(b) + return tl::to_qstring (search_string_from_expanded_names (pins_from_id (id))); } else if (is_id_circuit_pin_net (id)) { - const db::Circuit *circuit = circuit_from_id (id); - const db::Pin *pin = pin_from_id (id); - if (pin) { - const db::Net *net = circuit->net_for_pin (pin->id ()); - if (net) { - return tl::to_qstring (net->expanded_name ()); - } - } - // TODO: in case of compare, use net_name(a)|net_name(b) + return tl::to_qstring (search_string_from_expanded_names (nets_from_circuit_pins (circuits_from_id (id), pins_from_id (id)))); } else if (is_id_circuit_device (id)) { - const db::Device *device = device_from_id (id); - if (device && device->device_class ()) { - return tl::to_qstring (device->device_class ()->name () + "|" + device->expanded_name ()); - } - // TODO: in case of compare, use class(a)|device_name(a)|class(b)|device_name(b) + IndexedNetlistModel::device_pair devices = devices_from_id (id); + std::pair device_classes = device_classes_from_devices (devices); + return tl::to_qstring (combine_search_strings (search_string_from_expanded_names (devices), search_string_from_names (device_classes))); } else if (is_id_circuit_device_terminal (id)) { - const db::Device *device = device_from_id (id); - if (device && device->device_class ()) { - size_t terminal = circuit_device_terminal_index_from_id (id); - if (device->device_class ()->terminal_definitions ().size () > terminal) { - const db::DeviceTerminalDefinition &td = device->device_class ()->terminal_definitions () [terminal]; - const db::Net *net = device->net_for_terminal (td.id ()); - if (net) { - return tl::to_qstring (td.name () + "|" + net->expanded_name ()); - } - } - } - // TODO: in case of compare, use terminal_name(a)|net_name(a)|terminal_name(b)|net_name(b) + IndexedNetlistModel::device_pair devices = devices_from_id (id); + std::pair device_classes = device_classes_from_devices (devices); + size_t terminal = circuit_device_terminal_index_from_id (id); + + std::pair termdefs = terminal_defs_from_device_classes (device_classes, terminal); + IndexedNetlistModel::net_pair nets = nets_from_device_terminals (devices, termdefs); + + return tl::to_qstring (combine_search_strings (search_string_from_names (termdefs), search_string_from_expanded_names (nets))); } else if (is_id_circuit_subcircuit (id)) { - const db::SubCircuit *subcircuit = subcircuit_from_id (id); - if (subcircuit && subcircuit->circuit_ref ()) { - return tl::to_qstring (subcircuit->circuit_ref ()->name () + "|" + subcircuit->expanded_name ()); - } - // TODO: in case of compare, use circuit_name(a)|subcircuit_name(a)|circuit_name(b)|subcircuit_name(b) + IndexedNetlistModel::subcircuit_pair subcircuits = subcircuits_from_id (id); + IndexedNetlistModel::circuit_pair circuit_refs = circuit_refs_from_subcircuits (subcircuits); + + return tl::to_qstring (combine_search_strings (search_string_from_names (circuit_refs), search_string_from_expanded_names (subcircuits))); } else if (is_id_circuit_subcircuit_pin (id)) { - const db::SubCircuit *subcircuit = subcircuit_from_id (id); - if (subcircuit && subcircuit->circuit () && subcircuit->circuit_ref ()) { - const db::Pin *pin = pin_from_id (id); - if (pin) { - const db::Net *net = subcircuit->net_for_pin (pin->id ()); - if (net) { - return tl::to_qstring (pin->name () + "|" + net->expanded_name ()); - } - } - } - // TODO: in case of compare, use pin_name(a)|net_name(a)|pin_name(b)|net_name(b) + IndexedNetlistModel::subcircuit_pair subcircuits = subcircuits_from_id (id); + IndexedNetlistModel::pin_pair pins = pins_from_id (id); + IndexedNetlistModel::net_pair nets = nets_from_subcircuit_pins (subcircuits, pins); + + return tl::to_qstring (combine_search_strings (search_string_from_names (pins), search_string_from_expanded_names (nets))); } else if (is_id_circuit_net (id)) { - const db::Net *net = net_from_id (id); - if (net) { - return tl::to_qstring (net->expanded_name ()); - } - // TODO: in case of compare, use name(a)|name(b) + return tl::to_qstring (search_string_from_expanded_names (nets_from_id (id))); } else if (is_id_circuit_net_pin (id)) { - const db::NetPinRef *ref = net_pinref_from_id (id); - if (ref && ref->pin ()) { - return tl::to_qstring (ref->pin ()->name ()); - } - // TODO: in case of compare, use pin_name(a)|pin_name(b) + IndexedNetlistModel::net_pin_pair pinrefs = net_pinrefs_from_id (id); + IndexedNetlistModel::pin_pair pins = pins_from_pinrefs (pinrefs); + + return tl::to_qstring (search_string_from_names (pins)); } else if (is_id_circuit_net_subcircuit_pin (id)) { - const db::NetSubcircuitPinRef *ref = net_subcircuit_pinref_from_id (id); - if (ref && ref->pin () && ref->subcircuit ()) { - const db::Circuit *circuit = ref->subcircuit ()->circuit_ref (); - if (circuit) { - return tl::to_qstring (ref->pin ()->name () + "|" + circuit->name () + "|" + ref->subcircuit ()->name ()); - } - } - // TODO: in case of compare, use pin_name(a)|circuit_name(a)|subcircuit_name(a)|pin_name(b)|circuit_name(b)|subcircuit_name(b) + IndexedNetlistModel::net_subcircuit_pin_pair pinrefs = net_subcircuit_pinrefs_from_id (id); + IndexedNetlistModel::subcircuit_pair subcircuits = subcircuits_from_pinrefs (pinrefs); + IndexedNetlistModel::circuit_pair circuit_refs = circuit_refs_from_subcircuits (subcircuits); + IndexedNetlistModel::pin_pair pins = pins_from_pinrefs (pinrefs); + + return tl::to_qstring (combine_search_strings (combine_search_strings (search_string_from_names (pins), search_string_from_names (circuit_refs)), search_string_from_expanded_names (subcircuits))); } else if (is_id_circuit_net_subcircuit_pin_others (id)) { - const db::NetSubcircuitPinRef *ref = net_subcircuit_pinref_from_id (id); + IndexedNetlistModel::net_subcircuit_pin_pair pinrefs = net_subcircuit_pinrefs_from_id (id); size_t other_index = circuit_net_subcircuit_pin_other_index_from_id (id); - if (ref && ref->pin () && ref->subcircuit ()) { - const db::Circuit *circuit = ref->subcircuit ()->circuit_ref (); - if (circuit && circuit->pin_by_id (other_index)) { - const db::Pin *pin = circuit->pin_by_id (other_index); - const db::Net *net = ref->subcircuit ()->net_for_pin (pin->id ()); - if (net) { - return tl::to_qstring (pin->name () + "|" + net->expanded_name ()); - } - } - } - // TODO: in case of compare, use pin_name(a)|net_name(a)|pin_name(b)|net_name(b) + IndexedNetlistModel::subcircuit_pair subcircuits = subcircuits_from_pinrefs (pinrefs); + IndexedNetlistModel::circuit_pair circuit_refs = circuit_refs_from_subcircuits (subcircuits); + + IndexedNetlistModel::pin_pair pins = mp_indexer->pin_from_index (circuit_refs, other_index); + IndexedNetlistModel::net_pair nets = nets_from_circuit_pins (circuit_refs, pins); + + return tl::to_qstring (combine_search_strings (search_string_from_names (pins), search_string_from_expanded_names (nets))); } else if (is_id_circuit_net_device_terminal (id)) { - const db::NetTerminalRef *ref = net_terminalref_from_id (id); - if (ref && ref->terminal_def () && ref->device () && ref->device ()->device_class ()) { - return tl::to_qstring (ref->terminal_def ()->name () + "|" + ref->device ()->device_class ()->name () + "|" + ref->device ()->expanded_name ()); - } - // TODO: in case of compare, use terminal_name(a)|device_class(a)|device_name(a)|terminal_name(b)|device_class(b)|device_name(b) + IndexedNetlistModel::net_terminal_pair termrefs = net_terminalrefs_from_id (id); + IndexedNetlistModel::device_pair devices = devices_from_termrefs (termrefs); + std::pair device_classes = device_classes_from_devices (devices); + std::pair termdefs = terminal_defs_from_terminal_refs (termrefs); + + return tl::to_qstring (combine_search_strings (combine_search_strings (search_string_from_names (termdefs), search_string_from_names (device_classes)), search_string_from_expanded_names (devices))); } else if (is_id_circuit_net_device_terminal_others (id)) { - const db::NetTerminalRef *ref = net_terminalref_from_id (id); + IndexedNetlistModel::net_terminal_pair termrefs = net_terminalrefs_from_id (id); size_t other_index = circuit_net_device_terminal_other_index_from_id (id); - if (ref && ref->device_class () && ref->device_class ()->terminal_definitions ().size () > other_index) { - const db::DeviceTerminalDefinition &def = ref->device_class ()->terminal_definitions ()[other_index]; - const db::Net *net = ref->device ()->net_for_terminal (def.id ()); - if (net) { - return tl::to_qstring (def.name () + "|" + net->expanded_name ()); - } - } - // TODO: in case of compare, use terminal_name(a)|net_name(a)|terminal_name(b)|net_name(b) + IndexedNetlistModel::device_pair devices = devices_from_termrefs (termrefs); + std::pair device_classes = device_classes_from_devices (devices); + std::pair termdefs = terminal_defs_from_device_classes (device_classes, other_index); + + IndexedNetlistModel::net_pair nets = nets_from_device_terminals (devices, termdefs); + + return tl::to_qstring (combine_search_strings (search_string_from_names (termdefs), search_string_from_expanded_names (nets))); } @@ -1280,6 +1719,11 @@ static QIcon icon_for_device (const db::DeviceClass *dc) return icon; } +static QIcon icon_for_devices (const std::pair &device_classes) +{ + return icon_for_device (device_classes.first ? device_classes.first : device_classes.second); +} + static QIcon icon_for_circuit () { QIcon icon; @@ -1335,8 +1779,10 @@ static QIcon connection_icon_with_color (const QColor &color) } QIcon -NetlistBrowserModel::icon_for_net (const db::Net *net) const +NetlistBrowserModel::icon_for_nets (const std::pair &nets) const { + const db::Net *net = nets.first; + if (mp_colorizer && mp_colorizer->has_color_for_net (net)) { QColor color = mp_colorizer->color_of_net (net); @@ -1355,8 +1801,10 @@ NetlistBrowserModel::icon_for_net (const db::Net *net) const } QIcon -NetlistBrowserModel::icon_for_connection (const db::Net *net) const +NetlistBrowserModel::icon_for_connection (const std::pair &nets) const { + const db::Net *net = nets.first; + if (mp_colorizer && mp_colorizer->has_color_for_net (net)) { QColor color = mp_colorizer->color_of_net (net); @@ -1385,20 +1833,20 @@ NetlistBrowserModel::icon (const QModelIndex &index) const return icon_for_pin (); } else if (is_id_circuit_net (id)) { - const db::Net *net = net_from_index (index); - return icon_for_net (net); + IndexedNetlistModel::net_pair nets = net_from_index (index); + return icon_for_nets (nets); } else if (is_id_circuit_device (id)) { - const db::Device *device = device_from_id (id); - if (device) { - return icon_for_device (device->device_class ()); - } + IndexedNetlistModel::device_pair devices = devices_from_id (id); + std::pair device_classes = device_classes_from_devices (devices); + + return icon_for_devices (device_classes); } else if (is_id_circuit_net_device_terminal_others (id) || is_id_circuit_net_subcircuit_pin_others (id)) { - const db::Net *net = net_from_index (index); - return icon_for_connection (net); + IndexedNetlistModel::net_pair nets = net_from_index (index); + return icon_for_connection (nets); } else if (is_id_circuit_subcircuit (id)) { return icon_for_circuit (); @@ -1408,10 +1856,11 @@ NetlistBrowserModel::icon (const QModelIndex &index) const return icon_for_circuit (); } else if (is_id_circuit_net_device_terminal (id)) { - const db::NetTerminalRef *ref = net_terminalref_from_id (id); - if (ref && ref->device ()) { - return icon_for_device (ref->device ()->device_class ()); - } + IndexedNetlistModel::net_terminal_pair termrefs = net_terminalrefs_from_id (id); + IndexedNetlistModel::device_pair devices = devices_from_termrefs (termrefs); + std::pair device_classes = device_classes_from_devices (devices); + + return icon_for_devices (device_classes); } @@ -1424,6 +1873,140 @@ NetlistBrowserModel::flags (const QModelIndex & /*index*/) const return Qt::ItemIsEnabled | Qt::ItemIsSelectable; } +static size_t device_rows_for (const db::Circuit *circuit) +{ + if (! circuit) { + return 0; + } else { + return circuit->device_count (); + } +} + +static size_t device_rows_for (const IndexedNetlistModel::circuit_pair &circuits) +{ + return std::max (device_rows_for (circuits.first), device_rows_for (circuits.second)); +} + +static size_t pin_rows_for (const db::Circuit *circuit) +{ + if (! circuit) { + return 0; + } else { + return circuit->pin_count (); + } +} + +static size_t pin_rows_for (const IndexedNetlistModel::circuit_pair &circuits) +{ + return std::max (pin_rows_for (circuits.first), pin_rows_for (circuits.second)); +} + +static size_t net_rows_for (const db::Circuit *circuit) +{ + if (! circuit) { + return 0; + } else { + return circuit->net_count (); + } +} + +static size_t net_rows_for (const IndexedNetlistModel::circuit_pair &circuits) +{ + return std::max (net_rows_for (circuits.first), net_rows_for (circuits.second)); +} + +static size_t subcircuit_rows_for (const db::Circuit *circuit) +{ + if (! circuit) { + return 0; + } else { + return circuit->subcircuit_count (); + } +} + +static size_t subcircuit_rows_for (const IndexedNetlistModel::circuit_pair &circuits) +{ + return std::max (subcircuit_rows_for (circuits.first), subcircuit_rows_for (circuits.second)); +} + +static size_t pin_rows_for (const db::Net *net) +{ + if (! net) { + return 0; + } else { + return net->pin_count (); + } +} + +static size_t pin_rows_for (const IndexedNetlistModel::net_pair &nets) +{ + return std::max (pin_rows_for (nets.first), pin_rows_for (nets.second)); +} + +static size_t subcircuit_rows_for (const db::Net *net) +{ + if (! net) { + return 0; + } else { + return net->subcircuit_pin_count (); + } +} + +static size_t subcircuit_rows_for (const IndexedNetlistModel::net_pair &nets) +{ + return std::max (subcircuit_rows_for (nets.first), subcircuit_rows_for (nets.second)); +} + +static size_t terminal_rows_for (const db::Net *net) +{ + if (! net) { + return 0; + } else { + return net->terminal_count (); + } +} + +static size_t terminal_rows_for (const IndexedNetlistModel::net_pair &nets) +{ + return std::max (terminal_rows_for (nets.first), terminal_rows_for (nets.second)); +} + +static size_t rows_for (const db::Device *device) +{ + if (! device || ! device->device_class ()) { + return 0; + } else { + return device->device_class ()->terminal_definitions ().size (); + } +} + +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::NetSubcircuitPinRef *ref) +{ + if (! ref || ! ref->subcircuit () || ! ref->subcircuit ()->circuit_ref ()) { + return 0; + } else { + return ref->subcircuit ()->circuit_ref ()->pin_count (); + } +} + +static size_t rows_for (const db::NetTerminalRef *ref) +{ + if (! ref || ! ref->device_class ()) { + return 0; + } else { + return ref->device_class ()->terminal_definitions ().size (); + } +} + bool NetlistBrowserModel::hasChildren (const QModelIndex &parent) const { @@ -1436,25 +2019,44 @@ NetlistBrowserModel::hasChildren (const QModelIndex &parent) const void *id = parent.internalPointer (); if (is_id_circuit (id)) { - const db::Circuit *circuit = circuit_from_id (id); - return circuit->device_count () + circuit->pin_count () + circuit->net_count () + circuit->subcircuit_count () > 0; + + IndexedNetlistModel::circuit_pair circuits = circuits_from_id (id); + return device_rows_for (circuits.first) > 0 || device_rows_for (circuits.second) > 0 || + subcircuit_rows_for (circuits.first) > 0 || subcircuit_rows_for (circuits.second) > 0 || + pin_rows_for (circuits.first) > 0 || pin_rows_for (circuits.second) > 0 || + net_rows_for (circuits.first) > 0 || net_rows_for (circuits.second) > 0; + } else if (is_id_circuit_pin (id)) { + return true; + } else if (is_id_circuit_device (id)) { - const db::Device *device = device_from_id (id); - return device->device_class () && ! device->device_class ()->terminal_definitions ().empty (); + + IndexedNetlistModel::device_pair devices = devices_from_id (id); + return rows_for (devices.first) > 0 || rows_for (devices.second) > 0; + } else if (is_id_circuit_subcircuit (id)) { - const db::SubCircuit *subcircuit = subcircuit_from_id (id); - return subcircuit->circuit_ref () && subcircuit->circuit_ref ()->pin_count () > 0; + + IndexedNetlistModel::subcircuit_pair subcircuits = subcircuits_from_id (id); + return rows_for (subcircuits.first) > 0 || rows_for (subcircuits.second) > 0; + } else if (is_id_circuit_net (id)) { - const db::Net *net = net_from_id (id); - return net->pin_count () + net->subcircuit_pin_count () + net->terminal_count () > 0; + + IndexedNetlistModel::net_pair nets = nets_from_id (id); + return pin_rows_for (nets.first) > 0 || pin_rows_for (nets.second) > 0 || + terminal_rows_for (nets.first) > 0 || terminal_rows_for (nets.second) > 0 || + subcircuit_rows_for (nets.first) > 0 || subcircuit_rows_for (nets.second) > 0; + } else if (is_id_circuit_net_subcircuit_pin (id)) { - const db::NetSubcircuitPinRef *ref = net_subcircuit_pinref_from_id (id); - return ref->subcircuit ()->circuit_ref () && ref->subcircuit ()->circuit_ref ()->pin_count () > 0; + + IndexedNetlistModel::net_subcircuit_pin_pair refs = net_subcircuit_pinrefs_from_id (id); + return rows_for (refs.first) > 0 || rows_for (refs.second) > 0; + } else if (is_id_circuit_net_device_terminal (id)) { - const db::NetTerminalRef *ref = net_terminalref_from_id (id); - return ref->device_class () && ! ref->device_class ()->terminal_definitions ().empty (); + + IndexedNetlistModel::net_terminal_pair refs = net_terminalrefs_from_id (id); + return rows_for (refs.first) > 0 || rows_for (refs.second) > 0; + } else { return false; } @@ -1469,6 +2071,7 @@ NetlistBrowserModel::headerData (int section, Qt::Orientation /*orientation*/, i if (section == 0) { return tr ("Object"); } else if (section == 1) { + // TODO: 2 and 3 columns return tr ("Name (Items)"); } } @@ -1492,20 +2095,23 @@ NetlistBrowserModel::index (int row, int column, const QModelIndex &parent) cons if (is_id_circuit (id)) { int r = row; - const db::Circuit *circuit = circuit_from_id (id); - if (r < int (circuit->pin_count ())) { + IndexedNetlistModel::circuit_pair circuits = circuits_from_id (id); + int rpins = int (pin_rows_for (circuits)); + if (r < rpins) { new_id = make_id_circuit_pin (circuit_index_from_id (id), size_t (r)); } else { - r -= int (circuit->pin_count ()); - if (r < int (circuit->net_count ())) { + r -= rpins; + int rnets = int (net_rows_for (circuits)); + if (r < int (rnets)) { new_id = make_id_circuit_net (circuit_index_from_id (id), size_t (r)); } else { - r -= int (circuit->net_count ()); - if (r < int (circuit->subcircuit_count ())) { + r -= int (rnets); + int rsubcircuits = int (subcircuit_rows_for (circuits)); + if (r < rsubcircuits) { new_id = make_id_circuit_subcircuit (circuit_index_from_id (id), size_t (r)); } else { - r -= int (circuit->subcircuit_count ()); - if (r < int (circuit->device_count ())) { + r -= rsubcircuits; + if (r < int (device_rows_for (circuits))) { new_id = make_id_circuit_device (circuit_index_from_id (id), size_t (r)); } } @@ -1527,16 +2133,18 @@ NetlistBrowserModel::index (int row, int column, const QModelIndex &parent) cons } else if (is_id_circuit_net (id)) { int r = row; - const db::Net *net = net_from_id (id); - if (r < int (net->terminal_count ())) { + IndexedNetlistModel::net_pair nets = nets_from_id (id); + int rterminals = int (terminal_rows_for (nets)); + if (r < rterminals){ new_id = make_id_circuit_net_device_terminal (circuit_index_from_id (id), circuit_net_index_from_id (id), size_t (r)); } else { - r -= int (net->terminal_count ()); - if (r < int (net->pin_count ())) { + r -= rterminals; + int rpins = int (pin_rows_for (nets)); + if (r < rpins) { new_id = make_id_circuit_net_pin (circuit_index_from_id (id), circuit_net_index_from_id (id), size_t (r)); } else { - r -= int (net->pin_count ()); - if (r < int (net->subcircuit_pin_count ())) { + r -= rpins; + if (r < int (subcircuit_rows_for (nets))) { new_id = make_id_circuit_net_subcircuit_pin (circuit_index_from_id (id), circuit_net_index_from_id (id), size_t (r)); } } @@ -1564,116 +2172,112 @@ NetlistBrowserModel::colors_changed () } QModelIndex -NetlistBrowserModel::index_from_net (const db::Net *net) const +NetlistBrowserModel::index_from_net (const std::pair &nets) const { - void *id = make_id_circuit_net (mp_indexer->circuit_index (net->circuit ()), mp_indexer->net_index (net)); + IndexedNetlistModel::circuit_pair circuits (nets.first ? nets.first->circuit () : 0, nets.second ? nets.second->circuit () : 0); + void *id = make_id_circuit_net (mp_indexer->circuit_index (circuits), mp_indexer->net_index (nets)); return index_from_id (id, 0); } -const db::Net * +QModelIndex +NetlistBrowserModel::index_from_net (const db::Net *net) const +{ + return index_from_net (std::make_pair (net, mp_indexer->second_net_for (net))); +} + +std::pair NetlistBrowserModel::net_from_index (const QModelIndex &index) const { void *id = index.internalPointer (); if (is_id_circuit_net (id)) { - return net_from_id (id); + return nets_from_id (id); } else if (is_id_circuit_device_terminal (id)) { - const db::Device *device = device_from_id (id); - if (device && device->device_class ()) { - size_t terminal = circuit_device_terminal_index_from_id (id); - if (device->device_class ()->terminal_definitions ().size () > terminal) { - return device->net_for_terminal (device->device_class ()->terminal_definitions () [terminal].id ()); - } - } + IndexedNetlistModel::device_pair devices = devices_from_id (id); + std::pair device_classes = device_classes_from_devices (devices); + + size_t terminal = circuit_device_terminal_index_from_id (id); + std::pair termdefs = terminal_defs_from_device_classes (device_classes, terminal); + + return nets_from_device_terminals (devices, termdefs); } else if (is_id_circuit_pin_net (id)) { - const db::Circuit *circuit = circuit_from_id (id); - const db::Pin *pin = pin_from_id (id); - if (pin) { - return circuit->net_for_pin (pin->id ()); - } + IndexedNetlistModel::circuit_pair circuits = circuits_from_id (id); + IndexedNetlistModel::pin_pair pins = pins_from_id (id); + return nets_from_circuit_pins (circuits, pins); } else if (is_id_circuit_subcircuit_pin (id)) { - const db::SubCircuit *subcircuit = subcircuit_from_id (id); - if (subcircuit && subcircuit->circuit () && subcircuit->circuit_ref ()) { - const db::Pin *pin = pin_from_id (id); - if (pin) { - return subcircuit->net_for_pin (pin->id ()); - } - } + IndexedNetlistModel::subcircuit_pair subcircuits = subcircuits_from_id (id); + IndexedNetlistModel::pin_pair pins = pins_from_id (id); + return nets_from_subcircuit_pins (subcircuits, pins); } else if (is_id_circuit_net_subcircuit_pin_others (id)) { - const db::NetSubcircuitPinRef *ref = net_subcircuit_pinref_from_id (id); + IndexedNetlistModel::net_subcircuit_pin_pair pinrefs = net_subcircuit_pinrefs_from_id (id); size_t other_index = circuit_net_subcircuit_pin_other_index_from_id (id); - if (ref && ref->pin () && ref->subcircuit ()) { - const db::Circuit *circuit = ref->subcircuit ()->circuit_ref (); - if (circuit && circuit->pin_by_id (other_index)) { - const db::Pin *pin = circuit->pin_by_id (other_index); - return ref->subcircuit ()->net_for_pin (pin->id ()); - } - } + IndexedNetlistModel::subcircuit_pair subcircuits = subcircuits_from_pinrefs (pinrefs); + IndexedNetlistModel::circuit_pair circuit_refs = circuit_refs_from_subcircuits (subcircuits); + IndexedNetlistModel::pin_pair pins = mp_indexer->pin_from_index (circuit_refs, other_index); + + return nets_from_subcircuit_pins (subcircuits, pins); } else if (is_id_circuit_net_device_terminal_others (id)) { - const db::NetTerminalRef *ref = net_terminalref_from_id (id); + IndexedNetlistModel::net_terminal_pair termrefs = net_terminalrefs_from_id (id); size_t other_index = circuit_net_device_terminal_other_index_from_id (id); - if (ref && ref->device_class () && ref->device_class ()->terminal_definitions ().size () > other_index) { - const db::DeviceTerminalDefinition &def = ref->device_class ()->terminal_definitions ()[other_index]; - return ref->device ()->net_for_terminal (def.id ()); - } + IndexedNetlistModel::device_pair devices = devices_from_termrefs (termrefs); + std::pair device_classes = device_classes_from_devices (devices); + std::pair termdefs = terminal_defs_from_device_classes (device_classes, other_index); + + return nets_from_device_terminals (devices, termdefs); } - return 0; + return std::make_pair ((const db::Net *) 0, (const db::Net *) 0); } -const db::Device * +std::pair NetlistBrowserModel::device_from_index (const QModelIndex &index) const { void *id = index.internalPointer (); if (is_id_circuit_device (id)) { - return device_from_id (id); + return devices_from_id (id); } else if (is_id_circuit_net_device_terminal (id)) { - const db::NetTerminalRef *ref = net_terminalref_from_id (id); - if (ref) { - return ref->device (); - } + IndexedNetlistModel::net_terminal_pair termrefs = net_terminalrefs_from_id (id); + return devices_from_termrefs (termrefs); } - return 0; + return std::make_pair ((const db::Device *) 0, (const db::Device *) 0); } -const db::SubCircuit * +std::pair NetlistBrowserModel::subcircuit_from_index (const QModelIndex &index) const { void *id = index.internalPointer (); if (is_id_circuit_subcircuit (id)) { - return subcircuit_from_id (id); + return subcircuits_from_id (id); } else if (is_id_circuit_net_subcircuit_pin (id)) { - const db::NetSubcircuitPinRef *ref = net_subcircuit_pinref_from_id (id); - if (ref) { - return ref->subcircuit (); - } + IndexedNetlistModel::net_subcircuit_pin_pair pinrefs = net_subcircuit_pinrefs_from_id (id); + return subcircuits_from_pinrefs (pinrefs); } - return 0; + return std::make_pair ((const db::SubCircuit *) 0, (const db::SubCircuit *) 0); } QModelIndex @@ -1693,8 +2297,8 @@ NetlistBrowserModel::index_from_id (void *id, int column) const } else if (is_id_circuit_net (id)) { - const db::Circuit *circuit = circuit_from_id (id); - return createIndex (int (circuit->pin_count () + circuit_net_index_from_id (id)), column, id); + IndexedNetlistModel::circuit_pair circuits = circuits_from_id (id); + return createIndex (int (pin_rows_for (circuits) + circuit_net_index_from_id (id)), column, id); } else if (is_id_circuit_net_device_terminal (id)) { @@ -1706,13 +2310,13 @@ NetlistBrowserModel::index_from_id (void *id, int column) const } else if (is_id_circuit_net_pin (id)) { - const db::Net *net = net_from_id (id); - return createIndex (net->terminal_count () + circuit_net_pin_index_from_id (id), column, id); + IndexedNetlistModel::net_pair nets = nets_from_id (id); + return createIndex (int (terminal_rows_for (nets) + circuit_net_pin_index_from_id (id)), column, id); } else if (is_id_circuit_net_subcircuit_pin (id)) { - const db::Net *net = net_from_id (id); - return createIndex (net->terminal_count () + net->pin_count () + circuit_net_subcircuit_pin_index_from_id (id), column, id); + IndexedNetlistModel::net_pair nets = nets_from_id (id); + return createIndex (int (terminal_rows_for (nets) + pin_rows_for (nets) + circuit_net_subcircuit_pin_index_from_id (id)), column, id); } else if (is_id_circuit_net_subcircuit_pin_others (id)) { @@ -1720,8 +2324,8 @@ NetlistBrowserModel::index_from_id (void *id, int column) const } else if (is_id_circuit_subcircuit (id)) { - const db::Circuit *circuit = circuit_from_id (id); - return createIndex (int (circuit->pin_count () + circuit->net_count () + circuit_subcircuit_index_from_id (id)), column, id); + IndexedNetlistModel::circuit_pair circuits = circuits_from_id (id); + return createIndex (int (pin_rows_for (circuits) + net_rows_for (circuits) + circuit_subcircuit_index_from_id (id)), column, id); } else if (is_id_circuit_subcircuit_pin (id)) { @@ -1729,8 +2333,8 @@ NetlistBrowserModel::index_from_id (void *id, int column) const } else if (is_id_circuit_device (id)) { - const db::Circuit *circuit = circuit_from_id (id); - return createIndex (int (circuit->pin_count () + circuit->net_count () + circuit->subcircuit_count () + circuit_device_index_from_id (id)), column, id); + IndexedNetlistModel::circuit_pair circuits = circuits_from_id (id); + return createIndex (int (pin_rows_for (circuits) + net_rows_for (circuits) + subcircuit_rows_for (circuits) + circuit_device_index_from_id (id)), column, id); } else if (is_id_circuit_device_terminal (id)) { @@ -1741,7 +2345,6 @@ NetlistBrowserModel::index_from_id (void *id, int column) const return QModelIndex (); } - QModelIndex NetlistBrowserModel::parent (const QModelIndex &index) const { @@ -1768,18 +2371,18 @@ NetlistBrowserModel::parent (const QModelIndex &index) const } else if (is_id_circuit_net_device_terminal (id) || is_id_circuit_net_pin (id) || is_id_circuit_net_subcircuit_pin (id)) { - const db::Circuit *circuit = circuit_from_id (id); - return createIndex (int (circuit->pin_count () + circuit_net_index_from_id (id)), column, make_id_circuit_net (circuit_index_from_id (id), circuit_net_index_from_id (id))); + IndexedNetlistModel::circuit_pair circuits = circuits_from_id (id); + return createIndex (int (pin_rows_for (circuits) + circuit_net_index_from_id (id)), column, make_id_circuit_net (circuit_index_from_id (id), circuit_net_index_from_id (id))); } else if (is_id_circuit_subcircuit_pin (id)) { - const db::Circuit *circuit = circuit_from_id (id); - return createIndex (int (circuit->pin_count () + circuit->net_count () + circuit_subcircuit_index_from_id (id)), column, make_id_circuit_subcircuit (circuit_index_from_id (id), circuit_subcircuit_index_from_id (id))); + IndexedNetlistModel::circuit_pair circuits = circuits_from_id (id); + return createIndex (int (pin_rows_for (circuits) + net_rows_for (circuits) + circuit_subcircuit_index_from_id (id)), column, make_id_circuit_subcircuit (circuit_index_from_id (id), circuit_subcircuit_index_from_id (id))); } else if (is_id_circuit_device_terminal (id)) { - const db::Circuit *circuit = circuit_from_id (id); - return createIndex (int (circuit->pin_count () + circuit->net_count () + circuit->subcircuit_count () + circuit_device_index_from_id (id)), column, make_id_circuit_device (circuit_index_from_id (id), circuit_device_index_from_id (id))); + IndexedNetlistModel::circuit_pair circuits = circuits_from_id (id); + return createIndex (int (pin_rows_for (circuits) + net_rows_for (circuits) + subcircuit_rows_for (circuits) + circuit_device_index_from_id (id)), column, make_id_circuit_device (circuit_index_from_id (id), circuit_device_index_from_id (id))); } else if (is_id_circuit_net_device_terminal_others (id)) { @@ -1787,8 +2390,8 @@ NetlistBrowserModel::parent (const QModelIndex &index) const } else if (is_id_circuit_net_subcircuit_pin_others (id)) { - const db::Net *net = net_from_id (id); - return createIndex (size_t (net->terminal_count () + net->pin_count () + circuit_net_subcircuit_pin_index_from_id (id)), column, make_id_circuit_net_subcircuit_pin (circuit_index_from_id (id), circuit_net_index_from_id (id), circuit_net_subcircuit_pin_index_from_id (id))); + IndexedNetlistModel::net_pair nets = nets_from_id (id); + return createIndex (size_t (terminal_rows_for (nets) + pin_rows_for (nets) + circuit_net_subcircuit_pin_index_from_id (id)), column, make_id_circuit_net_subcircuit_pin (circuit_index_from_id (id), circuit_net_index_from_id (id), circuit_net_subcircuit_pin_index_from_id (id))); } @@ -1810,27 +2413,37 @@ NetlistBrowserModel::rowCount (const QModelIndex &parent) const if (is_id_circuit (id)) { - const db::Circuit *circuit = circuit_from_id (id); - return int (circuit->pin_count () + circuit->net_count () + circuit->subcircuit_count () + circuit->device_count ()); + IndexedNetlistModel::circuit_pair circuits = circuits_from_id (id); + return int (pin_rows_for (circuits) + net_rows_for (circuits) + subcircuit_rows_for (circuits) + device_rows_for (circuits)); } else if (is_id_circuit_pin (id)) { return 1; - } else if (is_id_circuit_device (id) || is_id_circuit_net_device_terminal (id)) { + } else if (is_id_circuit_device (id)) { - const db::Device *device = device_from_id (id); - return int (device->device_class () ? device->device_class ()->terminal_definitions ().size () : 0); + IndexedNetlistModel::device_pair devices = devices_from_id (id); + return int (std::max (rows_for (devices.first), rows_for (devices.second))); - } else if (is_id_circuit_subcircuit (id) || is_id_circuit_net_subcircuit_pin (id)) { + } else if (is_id_circuit_subcircuit (id)) { - const db::SubCircuit *subcircuit = subcircuit_from_id (id); - return int (subcircuit->circuit_ref () ? subcircuit->circuit_ref ()->pin_count () : 0); + IndexedNetlistModel::subcircuit_pair subcircuits = subcircuits_from_id (id); + return int (std::max (rows_for (subcircuits.first), rows_for (subcircuits.second))); + + } else if (is_id_circuit_net_subcircuit_pin (id)) { + + IndexedNetlistModel::net_subcircuit_pin_pair refs = net_subcircuit_pinrefs_from_id (id); + return std::max (rows_for (refs.first), rows_for (refs.second)); + + } else if (is_id_circuit_net_device_terminal (id)) { + + IndexedNetlistModel::net_terminal_pair refs = net_terminalrefs_from_id (id); + return std::max (rows_for (refs.first), rows_for (refs.second)); } else if (is_id_circuit_net (id)) { - const db::Net *net = net_from_id (id); - return int (net->terminal_count () + net->pin_count () + net->subcircuit_pin_count ()); + IndexedNetlistModel::net_pair nets = nets_from_id (id); + return int (terminal_rows_for (nets) + pin_rows_for (nets) + subcircuit_rows_for (nets)); } @@ -1839,93 +2452,95 @@ NetlistBrowserModel::rowCount (const QModelIndex &parent) const return 0; } -const db::Circuit * -NetlistBrowserModel::circuit_from_id (void *id) const +std::pair +NetlistBrowserModel::circuits_from_id (void *id) const { size_t index = circuit_index_from_id (id); return mp_indexer->circuit_from_index (index); } -const db::Net * -NetlistBrowserModel::net_from_id (void *id) const +std::pair +NetlistBrowserModel::nets_from_id (void *id) const { - const db::Circuit *circuit = circuit_from_id (id); + IndexedNetlistModel::circuit_pair circuits = circuits_from_id (id); size_t index = circuit_net_index_from_id (id); - return mp_indexer->net_from_index (circuit, index); + return mp_indexer->net_from_index (circuits, index); } -const db::NetSubcircuitPinRef * -NetlistBrowserModel::net_subcircuit_pinref_from_id (void *id) const +std::pair +NetlistBrowserModel::net_subcircuit_pinrefs_from_id (void *id) const { - const db::Net *net = net_from_id (id); + IndexedNetlistModel::net_pair nets = nets_from_id (id); size_t index = circuit_net_subcircuit_pin_index_from_id (id); - return mp_indexer->net_subcircuit_pinref_from_index (net, index); + return mp_indexer->net_subcircuit_pinref_from_index (nets, index); } -const db::NetPinRef * -NetlistBrowserModel::net_pinref_from_id (void *id) const +std::pair +NetlistBrowserModel::net_pinrefs_from_id (void *id) const { - const db::Net *net = net_from_id (id); + IndexedNetlistModel::net_pair nets = nets_from_id (id); size_t index = circuit_net_pin_index_from_id (id); - return mp_indexer->net_pinref_from_index (net, index); + return mp_indexer->net_pinref_from_index (nets, index); } -const db::NetTerminalRef * -NetlistBrowserModel::net_terminalref_from_id (void *id) const +std::pair +NetlistBrowserModel::net_terminalrefs_from_id (void *id) const { - const db::Net *net = net_from_id (id); + IndexedNetlistModel::net_pair nets = nets_from_id (id); size_t index = circuit_net_device_terminal_index_from_id (id); - return mp_indexer->net_terminalref_from_index (net, index); + return mp_indexer->net_terminalref_from_index (nets, index); } -const db::Device * -NetlistBrowserModel::device_from_id (void *id) const +std::pair +NetlistBrowserModel::devices_from_id (void *id) const { - const db::Circuit *circuit = circuit_from_id (id); + IndexedNetlistModel::circuit_pair circuits = circuits_from_id (id); size_t index = circuit_device_index_from_id (id); - return mp_indexer->device_from_index (circuit, index); + return mp_indexer->device_from_index (circuits, index); } -const db::Pin * -NetlistBrowserModel::pin_from_id (void *id) const +std::pair +NetlistBrowserModel::pins_from_id (void *id) const { if (is_id_circuit_subcircuit_pin (id)) { - const db::SubCircuit *subcircuit = subcircuit_from_id (id); - const db::Circuit *circuit = subcircuit->circuit_ref (); + IndexedNetlistModel::subcircuit_pair subcircuits = subcircuits_from_id (id); + IndexedNetlistModel::circuit_pair circuit_refs = circuit_refs_from_subcircuits (subcircuits); + size_t index = circuit_subcircuit_pin_index_from_id (id); - return mp_indexer->pin_from_index (circuit, index); + return mp_indexer->pin_from_index (circuit_refs, index); } else { - const db::Circuit *circuit = circuit_from_id (id); + IndexedNetlistModel::circuit_pair circuits = circuits_from_id (id); + size_t index = circuit_pin_index_from_id (id); - return mp_indexer->pin_from_index (circuit, index); + return mp_indexer->pin_from_index (circuits, index); } } -const db::SubCircuit * -NetlistBrowserModel::subcircuit_from_id (void *id) const +std::pair +NetlistBrowserModel::subcircuits_from_id (void *id) const { if (is_id_circuit_subcircuit_pin (id) || is_id_circuit_subcircuit (id)) { - const db::Circuit *circuit = circuit_from_id (id); + IndexedNetlistModel::circuit_pair circuits = circuits_from_id (id); size_t index = circuit_subcircuit_index_from_id (id); - return mp_indexer->subcircuit_from_index (circuit, index); + return mp_indexer->subcircuit_from_index (circuits, index); } else { - const db::NetSubcircuitPinRef *pinref = net_subcircuit_pinref_from_id (id); - return pinref ? pinref->subcircuit () : 0; + IndexedNetlistModel::net_subcircuit_pin_pair pinrefs = net_subcircuit_pinrefs_from_id (id); + return subcircuits_from_pinrefs (pinrefs); } } diff --git a/src/laybasic/laybasic/layNetlistBrowserModel.h b/src/laybasic/laybasic/layNetlistBrowserModel.h index d2507d79c..c61d232e2 100644 --- a/src/laybasic/laybasic/layNetlistBrowserModel.h +++ b/src/laybasic/laybasic/layNetlistBrowserModel.h @@ -123,11 +123,13 @@ public: QModelIndex index_from_id (void *id, int column) const; - const db::Net *net_from_index (const QModelIndex &index) const; + std::pair net_from_index (const QModelIndex &index) const; + QModelIndex index_from_net (const std::pair &net) const; QModelIndex index_from_net (const db::Net *net) const; - const db::SubCircuit *subcircuit_from_index (const QModelIndex &index) const; - const db::Device *device_from_index (const QModelIndex &index) const; + std::pair subcircuit_from_index (const QModelIndex &index) const; + + std::pair device_from_index (const QModelIndex &index) const; private slots: void colors_changed (); @@ -174,30 +176,30 @@ private: size_t circuit_net_subcircuit_pin_other_index_from_id (void *id) const; size_t circuit_net_device_terminal_index_from_id (void *id) const; size_t circuit_net_device_terminal_other_index_from_id (void *id) const; - const db::Circuit *circuit_from_id (void *id) const; - const db::Net *net_from_id (void *id) const; - const db::NetSubcircuitPinRef *net_subcircuit_pinref_from_id (void *id) const; - const db::NetTerminalRef *net_terminalref_from_id (void *id) const; - const db::NetPinRef *net_pinref_from_id (void *id) const; - const db::Device *device_from_id (void *id) const; - const db::Pin *pin_from_id (void *id) const; - const db::SubCircuit *subcircuit_from_id (void *id) const; + std::pair circuits_from_id (void *id) const; + std::pair nets_from_id (void *id) const; + std::pair net_subcircuit_pinrefs_from_id (void *id) const; + std::pair net_terminalrefs_from_id (void *id) const; + std::pair net_pinrefs_from_id (void *id) const; + std::pair devices_from_id (void *id) const; + std::pair pins_from_id (void *id) const; + std::pair subcircuits_from_id (void *id) const; QString text (const QModelIndex &index) const; QString search_text (const QModelIndex &index) const; QIcon icon (const QModelIndex &index) const; - QString make_link_to (const db::Net *net) const; - QString make_link_to (const db::Device *device) const; - QString make_link_to (const db::Pin *pin, const db::Circuit *circuit) const; - QString make_link_to (const db::Circuit *circuit) const; - QString make_link_to (const db::SubCircuit *sub_circuit) const; + QString make_link_to (const std::pair &nets) const; + QString make_link_to (const std::pair &devices) const; + QString make_link_to (const std::pair &pins, const std::pair &circuits) const; + QString make_link_to (const std::pair &circuits) const; + QString make_link_to (const std::pair &sub_circuits) const; - db::Netlist *netlist () const + std::pair netlists () const { - return const_cast (mp_l2ndb->netlist ()); + return std::pair (mp_l2ndb->netlist (), 0); } - QIcon icon_for_net (const db::Net *net) const; - QIcon icon_for_connection (const db::Net *net) const; + QIcon icon_for_nets (const std::pair &net) const; + QIcon icon_for_connection (const std::pair &net) const; db::LayoutToNetlist *mp_l2ndb; NetColorizer *mp_colorizer; diff --git a/src/laybasic/laybasic/layNetlistBrowserPage.cc b/src/laybasic/laybasic/layNetlistBrowserPage.cc index ab82cd71e..a382a836d 100644 --- a/src/laybasic/laybasic/layNetlistBrowserPage.cc +++ b/src/laybasic/laybasic/layNetlistBrowserPage.cc @@ -320,7 +320,7 @@ NetlistBrowserPage::selected_nets () QModelIndexList selection = directory_tree->selectionModel ()->selectedIndexes (); for (QModelIndexList::const_iterator i = selection.begin (); i != selection.end (); ++i) { if (i->column () == 0) { - const db::Net *net = model->net_from_index (*i); + const db::Net *net = model->net_from_index (*i).first; if (net) { nets.push_back (net); } @@ -341,7 +341,7 @@ NetlistBrowserPage::selected_subcircuits () QModelIndexList selection = directory_tree->selectionModel ()->selectedIndexes (); for (QModelIndexList::const_iterator i = selection.begin (); i != selection.end (); ++i) { if (i->column () == 0) { - const db::SubCircuit *subcircuit = model->subcircuit_from_index (*i); + const db::SubCircuit *subcircuit = model->subcircuit_from_index (*i).first; if (subcircuit) { subcircuits.push_back (subcircuit); } @@ -362,7 +362,7 @@ NetlistBrowserPage::selected_devices () QModelIndexList selection = directory_tree->selectionModel ()->selectedIndexes (); for (QModelIndexList::const_iterator i = selection.begin (); i != selection.end (); ++i) { if (i->column () == 0) { - const db::Device *device = model->device_from_index (*i); + const db::Device *device = model->device_from_index (*i).first; if (device) { devices.push_back (device); }