diff --git a/qucs/CMakeLists.txt b/qucs/CMakeLists.txt index 48f3bc927..cbae80c3c 100755 --- a/qucs/CMakeLists.txt +++ b/qucs/CMakeLists.txt @@ -132,6 +132,7 @@ SET(QUCS_SRCS SET(QUCS_HDRS element.h +conductor.h main.h messagedock.h misc.h diff --git a/qucs/conductor.h b/qucs/conductor.h new file mode 100644 index 000000000..70746e331 --- /dev/null +++ b/qucs/conductor.h @@ -0,0 +1,17 @@ + +#ifndef CONDUCTOR_H +#define CONDUCTOR_H +#include "element.h" + +class WireLabel; + +/** \class Conductor + * \brief label for Node and Wire classes + * + */ +class Conductor : public Element { +public: + WireLabel *Label; +}; + +#endif \ No newline at end of file diff --git a/qucs/dialogs/sweepdialog.cpp b/qucs/dialogs/sweepdialog.cpp index ea7ff3160..b0567e20b 100644 --- a/qucs/dialogs/sweepdialog.cpp +++ b/qucs/dialogs/sweepdialog.cpp @@ -188,13 +188,13 @@ Graph* SweepDialog::setBiasPoints(QHash *NodeVals) if(pn->Name.isEmpty()) continue; pn->x1 = 0; - if(pn->Connections.count() < 2) { + if(pn->conn_count() < 2) { pn->Name = ""; // no text at open nodes continue; } else { hasNoComp = true; - for(pe = pn->Connections.first(); pe!=0; pe = pn->Connections.next()) + for(auto *pe : *pn) if(pe->Type == isWire) { if( ((Wire*)pe)->isHorizontal() ) pn->x1 |= 2; } @@ -232,7 +232,7 @@ Graph* SweepDialog::setBiasPoints(QHash *NodeVals) } - for(pe = pn->Connections.first(); pe!=0; pe = pn->Connections.next()) + for(auto pe : *pn) if(pe->Type == isWire) { if( ((Wire*)pe)->Port1 != pn ) // no text at next node ((Wire*)pe)->Port1->Name = ""; @@ -269,7 +269,7 @@ Graph* SweepDialog::setBiasPoints(QHash *NodeVals) } - for(pe = pn->Connections.first(); pe!=0; pe = pn->Connections.next()) + for(auto pe : *pn) if(pe->Type == isWire) { if( ((Wire*)pe)->isHorizontal() ) pn->x1 |= 2; } @@ -288,7 +288,7 @@ Graph* SweepDialog::setBiasPoints(QHash *NodeVals) pn->Name = misc::num2str(NodeVals->value(src_nam))+"A"; } else pn->Name = "0A"; - for(pe = pn->Connections.first(); pe!=0; pe = pn->Connections.next()) + for(auto pe : *pn) if(pe->Type == isWire) { if( ((Wire*)pe)->isHorizontal() ) pn->x1 |= 2; } diff --git a/qucs/element.h b/qucs/element.h index 94e3c6509..d37a5349c 100644 --- a/qucs/element.h +++ b/qucs/element.h @@ -41,7 +41,6 @@ #include class Node; -class WireLabel; class Schematic; namespace qucs { // otherwise conflict with @@ -207,14 +206,4 @@ class Element { int cx, cy, x1, y1, x2, y2; // center and relative boundings }; - -/** \class Conductor - * \brief label for Node and Wire classes - * - */ -class Conductor : public Element { -public: - WireLabel *Label; -}; - #endif diff --git a/qucs/mouseactions.h b/qucs/mouseactions.h index 648c01394..b32c8bfaf 100644 --- a/qucs/mouseactions.h +++ b/qucs/mouseactions.h @@ -24,6 +24,7 @@ #include class Wire; +class WireLabel; class Schematic; class Diagram; class QPainter; diff --git a/qucs/node.cpp b/qucs/node.cpp index 07ff9f1c0..4cb81d229 100644 --- a/qucs/node.cpp +++ b/qucs/node.cpp @@ -20,15 +20,15 @@ #include -Node::Node(int _x, int _y) +Node::Node(int x, int y) { Label = 0; Type = isNode; State = 0; DType = ""; - cx = _x; - cy = _y; + cx = x; + cy = y; } Node::~Node() @@ -38,7 +38,7 @@ Node::~Node() void Node::paint(QPainter* painter) const { painter->save(); - switch(Connections.count()) { + switch(connections.size()) { case 1: if (Label) { painter->fillRect(cx-2, cy-2, 4, 4, Qt::darkBlue); // open but labeled @@ -50,7 +50,7 @@ void Node::paint(QPainter* painter) const { return; case 2: - if (Connections.getFirst()->Type == isWire && Connections.getLast()->Type == isWire) { + if (connections.front()->Type == isWire && connections.back()->Type == isWire) { painter->restore(); return; } @@ -61,31 +61,39 @@ void Node::paint(QPainter* painter) const { painter->setBrush(Qt::darkBlue); // more than 2 connections painter->setPen(QPen(Qt::darkBlue,1)); painter->drawEllipse(cx-3, cy-3, 6, 6); - painter->setBrush(Qt::NoBrush); } painter->restore(); } -// ---------------------------------------------------------------- -bool Node::getSelected(int x_, int y_) +bool Node::getSelected(int x, int y) { - if(cx-5 <= x_) if(cx+5 >= x_) if(cy-5 <= y_) if(cy+5 >= y_) - return true; - - return false; + return cx - 5 <= x && x <= cx + 5 && cy - 5 <= y && y <= cy + 5; } -// ---------------------------------------------------------------- -void Node::setName(const QString& Name_, const QString& Value_, int x_, int y_) +void Node::setName(const QString& name, const QString& value, int x, int y) { - if(Name_.isEmpty() && Value_.isEmpty()) { - if(Label) delete Label; - Label = 0; + if (name.isEmpty() && value.isEmpty()) { + if (Label) { + delete Label; + Label = nullptr; + } return; } - if(!Label) Label = new WireLabel(Name_, cx, cy, x_, y_, isNodeLabel); - else Label->setName(Name_); + if (!Label) { + Label = new WireLabel(name, cx, cy, x, y, isNodeLabel); + } + else { + Label->setName(name); + } Label->pOwner = this; - Label->initValue = Value_; + Label->initValue = value; } + +Element* Node::other_than(Element* elem) const +{ + auto other = std::find_if_not(connections.begin(), connections.end(), [elem](auto o){return o == elem;} + ); + + return other == connections.end() ? nullptr : *other; +} \ No newline at end of file diff --git a/qucs/node.h b/qucs/node.h index ec94a505c..68c842f4c 100644 --- a/qucs/node.h +++ b/qucs/node.h @@ -18,24 +18,98 @@ #ifndef NODE_H #define NODE_H -#include "element.h" - -#include "qt3_compat/qt_compat.h" - +#include "conductor.h" +#include class Node : public Conductor { public: - Node(int, int); + Node(int x, int y); ~Node(); void paint(QPainter* painter) const; bool getSelected(int, int); - void setName(const QString&, const QString&, int x_=0, int y_=0); + void setName(const QString&, const QString&, int x=0, int y=0); + + // Add an element to the node's connections. + // No-op if element is already connected. + void connect(Element* connectable); + + // Remove element from the node's connections. + void disconnect(Element* connectable); + + // Tells if an element is among node's connections. + bool is_connected(Element* connectable) const; + + std::size_t conn_count() const; + + // Returns one of node's connections or nullptr when + // there is no connections + Element* any() const; + + // Returns an element from node's connections which is + // not equal to e; nullptr if there is no such element + Element* other_than(Element* e) const; + + using const_iterator = std::list::const_iterator; + const_iterator begin() const; + const_iterator end() const; - Q3PtrList Connections; QString Name; // node name used by creation of netlist QString DType; // type of node (used by digital files) int State; // remember some things during some operations + +private: + // Nodes usually have quite a few connections. In ideal case, when all wire + // placement optimizations work properly, there can be at most four connections + // to a single node because Qucs-S allows only orthogonal element placement. + // + // Additions/deletions are frequent and made in random order. Considering + // all that I think the doubly-linked list is a good choice here. + // + // A node doesn't claim ownership of any connected object, storing raw pointers is OK. + // + // Long-term TODO: refactor so that node will keep only pointers to *connectable* + // objects, i.e. components and wires. Paintings, graphs, wirelabels, + // etc., are Elements too, it's just wrong to use so generic type. + std::list connections; }; +inline void Node::connect(Element* connectable) +{ + if (is_connected(connectable)) { + return; + } + connections.push_front(connectable); +} + +inline void Node::disconnect(Element* connectable) +{ + connections.remove(connectable); +} + +inline bool Node::is_connected(Element *connectable) const +{ + return std::find(connections.begin(), connections.end(), connectable) != connections.end(); +} + +inline std::size_t Node::conn_count() const +{ + return connections.size(); +} + +inline Node::const_iterator Node::begin() const +{ + return connections.begin(); +} + +inline Node::const_iterator Node::end() const +{ + return connections.end(); +} + +inline Element* Node::any() const +{ + return connections.empty() ? nullptr : connections.front(); +} + #endif diff --git a/qucs/schematic.cpp b/qucs/schematic.cpp index cdf986564..344210d0a 100644 --- a/qucs/schematic.cpp +++ b/qucs/schematic.cpp @@ -807,7 +807,7 @@ void Schematic::paintSchToViewpainter(QPainter* painter, bool printAll) { } for (auto* node : *Nodes) { - for (auto* connected : node->Connections) { + for (auto* connected : *node) { if (should_draw(connected)) { draw_preserve_selection(node, painter); break; @@ -2133,7 +2133,7 @@ bool Schematic::elementsOnGrid() // rescue non-selected node labels for (Port *pp : pc->Ports) if (pp->Connection->Label) - if (pp->Connection->Connections.count() < 2) { + if (pp->Connection->conn_count() < 2) { LabelCache.append(pp->Connection->Label); pp->Connection->Label->pOwner = 0; pp->Connection->Label = 0; @@ -2170,12 +2170,12 @@ bool Schematic::elementsOnGrid() // rescue non-selected node label pLabel = nullptr; if (pw->Port1->Label) { - if (pw->Port1->Connections.count() < 2) { + if (pw->Port1->conn_count() < 2) { pLabel = pw->Port1->Label; pw->Port1->Label = nullptr; } } else if (pw->Port2->Label) { - if (pw->Port2->Connections.count() < 2) { + if (pw->Port2->conn_count() < 2) { pLabel = pw->Port2->Label; pw->Port2->Label = nullptr; } diff --git a/qucs/schematic_element.cpp b/qucs/schematic_element.cpp index 62839552b..603ffe41f 100644 --- a/qucs/schematic_element.cpp +++ b/qucs/schematic_element.cpp @@ -19,8 +19,6 @@ #include "portsymbol.h" #include "schematic.h" -#include -#include /** @@ -64,7 +62,7 @@ Node* Schematic::insertNode(int x, int y, Element *e) for(pn = Nodes->first(); pn != 0; pn = Nodes->next()) // check every node if(pn->cx == x) if(pn->cy == y) { - pn->Connections.append(e); + pn->connect(e); break; } @@ -72,7 +70,7 @@ Node* Schematic::insertNode(int x, int y, Element *e) { pn = new Node(x, y); Nodes->append(pn); - pn->Connections.append(e); // connect schematic node to component node + pn->connect(e); // connect schematic node to component node } else return pn; // return, if node is not new @@ -128,7 +126,7 @@ int Schematic::insertWireNode1(Wire *w) if(pn != 0) { - pn->Connections.append(w); + pn->connect(w); w->Port1 = pn; return 2; // node is not new } @@ -154,7 +152,7 @@ int Schematic::insertWireNode1(Wire *w) { // one part of the wire lies within an existing wire // the other part not - if(ptr2->Port2->Connections.count() == 1) + if(ptr2->Port2->conn_count() == 1) { w->y1 = ptr2->y1; w->Port1 = ptr2->Port1; @@ -163,8 +161,8 @@ int Schematic::insertWireNode1(Wire *w) w->Label = ptr2->Label; w->Label->pOwner = w; } - ptr2->Port1->Connections.removeRef(ptr2); // two -> one wire - ptr2->Port1->Connections.append(w); + ptr2->Port1->disconnect(ptr2); // two -> one wire + ptr2->Port1->connect(w); Nodes->removeRef(ptr2->Port2); Wires->removeRef(ptr2); return 2; @@ -173,7 +171,7 @@ int Schematic::insertWireNode1(Wire *w) { w->y1 = ptr2->y2; w->Port1 = ptr2->Port2; - ptr2->Port2->Connections.append(w); // shorten new wire + ptr2->Port2->connect(w); // shorten new wire return 2; } } @@ -195,7 +193,7 @@ int Schematic::insertWireNode1(Wire *w) { // one part of the wire lies within an existing wire // the other part not - if(ptr2->Port2->Connections.count() == 1) + if(ptr2->Port2->conn_count() == 1) { w->x1 = ptr2->x1; w->Port1 = ptr2->Port1; @@ -204,8 +202,8 @@ int Schematic::insertWireNode1(Wire *w) w->Label = ptr2->Label; w->Label->pOwner = w; } - ptr2->Port1->Connections.removeRef(ptr2); // two -> one wire - ptr2->Port1->Connections.append(w); + ptr2->Port1->disconnect(ptr2); // two -> one wire + ptr2->Port1->connect(w); Nodes->removeRef(ptr2->Port2); Wires->removeRef(ptr2); return 2; @@ -214,7 +212,7 @@ int Schematic::insertWireNode1(Wire *w) { w->x1 = ptr2->x2; w->Port1 = ptr2->Port2; - ptr2->Port2->Connections.append(w); // shorten new wire + ptr2->Port2->connect(w); // shorten new wire return 2; } } @@ -224,7 +222,7 @@ int Schematic::insertWireNode1(Wire *w) pn = new Node(w->x1, w->y1); // create new node Nodes->append(pn); - pn->Connections.append(w); // connect schematic node to the new wire + pn->connect(w); // connect schematic node to the new wire w->Port1 = pn; // split the wire into two wires @@ -234,7 +232,7 @@ int Schematic::insertWireNode1(Wire *w) pn = new Node(w->x1, w->y1); // create new node Nodes->append(pn); - pn->Connections.append(w); // connect schematic node to the new wire + pn->connect(w); // connect schematic node to the new wire w->Port1 = pn; return 1; } @@ -246,14 +244,20 @@ bool Schematic::connectHWires1(Wire *w) Wire *pw; Node *n = w->Port1; - pw = (Wire*)n->Connections.last(); // last connection is the new wire itself - for(pw = (Wire*)n->Connections.prev(); pw!=0; pw = (Wire*)n->Connections.prev()) - { - if(pw->Type != isWire) continue; - if(!pw->isHorizontal()) continue; + for (auto* connected : *n) { + if (connected == w || connected->Type != isWire) { + continue; + } + + pw = dynamic_cast(connected); + + if (!pw->isHorizontal()) { + continue; + } + if(pw->x1 < w->x1) { - if(n->Connections.count() != 2) continue; + if(n->conn_count() != 2) continue; if(pw->Label) { w->Label = pw->Label; @@ -268,18 +272,18 @@ bool Schematic::connectHWires1(Wire *w) w->x1 = pw->x1; w->Port1 = pw->Port1; // new wire lengthens an existing one Nodes->removeRef(n); - w->Port1->Connections.removeRef(pw); - w->Port1->Connections.append(w); + w->Port1->disconnect(pw); + w->Port1->connect(w); Wires->removeRef(pw); return true; } if(pw->x2 >= w->x2) // new wire lies within an existing one ? { - w->Port1->Connections.removeRef(w); // second node not yet made + w->Port1->disconnect(w); // second node not yet made delete w; return false; } - if(pw->Port2->Connections.count() < 2) + if(pw->Port2->conn_count() < 2) { // existing wire lies within the new one if(pw->Label) @@ -287,15 +291,15 @@ bool Schematic::connectHWires1(Wire *w) w->Label = pw->Label; w->Label->pOwner = w; } - pw->Port1->Connections.removeRef(pw); + pw->Port1->disconnect(pw); Nodes->removeRef(pw->Port2); Wires->removeRef(pw); return true; } w->x1 = pw->x2; // shorten new wire according to an existing one - w->Port1->Connections.removeRef(w); + w->Port1->disconnect(w); w->Port1 = pw->Port2; - w->Port1->Connections.append(w); + w->Port1->connect(w); return true; } @@ -309,14 +313,20 @@ bool Schematic::connectVWires1(Wire *w) Wire *pw; Node *n = w->Port1; - pw = (Wire*)n->Connections.last(); // last connection is the new wire itself - for(pw = (Wire*)n->Connections.prev(); pw!=0; pw = (Wire*)n->Connections.prev()) - { - if(pw->Type != isWire) continue; - if(pw->isHorizontal()) continue; + for (auto* connected : *n) { + if (connected == w || connected->Type != isWire) { + continue; + } + + pw = dynamic_cast(connected); + + if (pw->isHorizontal()) { + continue; + } + if(pw->y1 < w->y1) { - if(n->Connections.count() != 2) continue; + if(n->conn_count() != 2) continue; if(pw->Label) { w->Label = pw->Label; @@ -331,18 +341,18 @@ bool Schematic::connectVWires1(Wire *w) w->y1 = pw->y1; w->Port1 = pw->Port1; // new wire lengthens an existing one Nodes->removeRef(n); - w->Port1->Connections.removeRef(pw); - w->Port1->Connections.append(w); + w->Port1->disconnect(pw); + w->Port1->connect(w); Wires->removeRef(pw); return true; } if(pw->y2 >= w->y2) // new wire lies complete within an existing one ? { - w->Port1->Connections.removeRef(w); // second node not yet made + w->Port1->disconnect(w); // second node not yet made delete w; return false; } - if(pw->Port2->Connections.count() < 2) + if(pw->Port2->conn_count() < 2) { // existing wire lies within the new one if(pw->Label) @@ -350,15 +360,15 @@ bool Schematic::connectVWires1(Wire *w) w->Label = pw->Label; w->Label->pOwner = w; } - pw->Port1->Connections.removeRef(pw); + pw->Port1->disconnect(pw); Nodes->removeRef(pw->Port2); Wires->removeRef(pw); return true; } w->y1 = pw->y2; // shorten new wire according to an existing one - w->Port1->Connections.removeRef(w); + w->Port1->disconnect(w); w->Port1 = pw->Port2; - w->Port1->Connections.append(w); + w->Port1->connect(w); return true; } @@ -378,7 +388,7 @@ int Schematic::insertWireNode2(Wire *w) if(pn != 0) { - pn->Connections.append(w); + pn->connect(w); w->Port2 = pn; return 2; // node is not new } @@ -398,7 +408,7 @@ int Schematic::insertWireNode2(Wire *w) { // one part of the wire lies within an existing wire // the other part not - if(ptr2->Port1->Connections.count() == 1) + if(ptr2->Port1->conn_count() == 1) { if(ptr2->Label) { @@ -407,8 +417,8 @@ int Schematic::insertWireNode2(Wire *w) } w->y2 = ptr2->y2; w->Port2 = ptr2->Port2; - ptr2->Port2->Connections.removeRef(ptr2); // two -> one wire - ptr2->Port2->Connections.append(w); + ptr2->Port2->disconnect(ptr2); // two -> one wire + ptr2->Port2->connect(w); Nodes->removeRef(ptr2->Port1); Wires->removeRef(ptr2); return 2; @@ -417,7 +427,7 @@ int Schematic::insertWireNode2(Wire *w) { w->y2 = ptr2->y1; w->Port2 = ptr2->Port1; - ptr2->Port1->Connections.append(w); // shorten new wire + ptr2->Port1->connect(w); // shorten new wire return 2; } } @@ -432,7 +442,7 @@ int Schematic::insertWireNode2(Wire *w) { // one part of the wire lies within an existing wire // the other part not - if(ptr2->Port1->Connections.count() == 1) + if(ptr2->Port1->conn_count() == 1) { if(ptr2->Label) { @@ -441,8 +451,8 @@ int Schematic::insertWireNode2(Wire *w) } w->x2 = ptr2->x2; w->Port2 = ptr2->Port2; - ptr2->Port2->Connections.removeRef(ptr2); // two -> one wire - ptr2->Port2->Connections.append(w); + ptr2->Port2->disconnect(ptr2); // two -> one wire + ptr2->Port2->connect(w); Nodes->removeRef(ptr2->Port1); Wires->removeRef(ptr2); return 2; @@ -451,7 +461,7 @@ int Schematic::insertWireNode2(Wire *w) { w->x2 = ptr2->x1; w->Port2 = ptr2->Port1; - ptr2->Port1->Connections.append(w); // shorten new wire + ptr2->Port1->connect(w); // shorten new wire return 2; } } @@ -460,7 +470,7 @@ int Schematic::insertWireNode2(Wire *w) pn = new Node(w->x2, w->y2); // create new node Nodes->append(pn); - pn->Connections.append(w); // connect schematic node to the new wire + pn->connect(w); // connect schematic node to the new wire w->Port2 = pn; // split the wire into two wires @@ -470,7 +480,7 @@ int Schematic::insertWireNode2(Wire *w) pn = new Node(w->x2, w->y2); // create new node Nodes->append(pn); - pn->Connections.append(w); // connect schematic node to the new wire + pn->connect(w); // connect schematic node to the new wire w->Port2 = pn; return 1; } @@ -482,14 +492,20 @@ bool Schematic::connectHWires2(Wire *w) Wire *pw; Node *n = w->Port2; - pw = (Wire*)n->Connections.last(); // last connection is the new wire itself - for(pw = (Wire*)n->Connections.prev(); pw!=0; pw = (Wire*)n->Connections.prev()) - { - if(pw->Type != isWire) continue; - if(!pw->isHorizontal()) continue; + for (auto* connected : *n) { + if (connected == w || connected->Type != isWire) { + continue; + } + + pw = dynamic_cast(connected); + + if (!pw->isHorizontal()) { + continue; + } + if(pw->x2 > w->x2) { - if(n->Connections.count() != 2) continue; + if(n->conn_count() != 2) continue; if(pw->Label) { w->Label = pw->Label; @@ -498,15 +514,15 @@ bool Schematic::connectHWires2(Wire *w) w->x2 = pw->x2; w->Port2 = pw->Port2; // new wire lengthens an existing one Nodes->removeRef(n); - w->Port2->Connections.removeRef(pw); - w->Port2->Connections.append(w); + w->Port2->disconnect(pw); + w->Port2->connect(w); Wires->removeRef(pw); return true; } // (if new wire lies complete within an existing one, was already // checked before) - if(pw->Port1->Connections.count() < 2) + if(pw->Port1->conn_count() < 2) { // existing wire lies within the new one if(pw->Label) @@ -514,15 +530,15 @@ bool Schematic::connectHWires2(Wire *w) w->Label = pw->Label; w->Label->pOwner = w; } - pw->Port2->Connections.removeRef(pw); + pw->Port2->disconnect(pw); Nodes->removeRef(pw->Port1); Wires->removeRef(pw); return true; } w->x2 = pw->x1; // shorten new wire according to an existing one - w->Port2->Connections.removeRef(w); + w->Port2->disconnect(w); w->Port2 = pw->Port1; - w->Port2->Connections.append(w); + w->Port2->connect(w); return true; } @@ -536,14 +552,20 @@ bool Schematic::connectVWires2(Wire *w) Wire *pw; Node *n = w->Port2; - pw = (Wire*)n->Connections.last(); // last connection is the new wire itself - for(pw = (Wire*)n->Connections.prev(); pw!=0; pw = (Wire*)n->Connections.prev()) - { - if(pw->Type != isWire) continue; - if(pw->isHorizontal()) continue; + for (auto* connected : *n) { + if (connected == w || connected->Type != isWire) { + continue; + } + + pw = dynamic_cast(connected); + + if (pw->isHorizontal()) { + continue; + } + if(pw->y2 > w->y2) { - if(n->Connections.count() != 2) continue; + if(n->conn_count() != 2) continue; if(pw->Label) { w->Label = pw->Label; @@ -552,15 +574,15 @@ bool Schematic::connectVWires2(Wire *w) w->y2 = pw->y2; w->Port2 = pw->Port2; // new wire lengthens an existing one Nodes->removeRef(n); - w->Port2->Connections.removeRef(pw); - w->Port2->Connections.append(w); + w->Port2->disconnect(pw); + w->Port2->connect(w); Wires->removeRef(pw); return true; } // (if new wire lies complete within an existing one, was already // checked before) - if(pw->Port1->Connections.count() < 2) + if(pw->Port1->conn_count() < 2) { // existing wire lies within the new one if(pw->Label) @@ -568,15 +590,15 @@ bool Schematic::connectVWires2(Wire *w) w->Label = pw->Label; w->Label->pOwner = w; } - pw->Port2->Connections.removeRef(pw); + pw->Port2->disconnect(pw); Nodes->removeRef(pw->Port1); Wires->removeRef(pw); return true; } w->y2 = pw->y1; // shorten new wire according to an existing one - w->Port2->Connections.removeRef(w); + w->Port2->disconnect(w); w->Port2 = pw->Port1; - w->Port2->Connections.append(w); + w->Port2->connect(w); return true; } @@ -642,7 +664,7 @@ int Schematic::insertWire(Wire *w) int n1, n2; Wire *pw, *nw; Node *pn, *pn2; - Element *pe; + // ................................................................ // Check if the new line covers existing nodes. // In order to also check new appearing wires -> use "for"-loop @@ -685,7 +707,7 @@ int Schematic::insertWire(Wire *w) n2 = 3; pn2 = pn; // check all connections of the current node - for(pe=pn->Connections.first(); pe!=0; pe=pn->Connections.next()) + for(auto* pe : *pn) { if(pe->Type != isWire) continue; nw = (Wire*)pe; @@ -694,18 +716,18 @@ int Schematic::insertWire(Wire *w) pn = nw->Port1; pn2 = nw->Port2; - n1 = pn->Connections.count(); - n2 = pn2->Connections.count(); + n1 = pn->conn_count(); + n2 = pn2->conn_count(); if(n1 == 1) { Nodes->removeRef(pn); // delete node 1 if open - pn2->Connections.removeRef(nw); // remove connection + pn2->disconnect(nw); // remove connection pn = pn2; } if(n2 == 1) { - pn->Connections.removeRef(nw); // remove connection + pn->disconnect(nw); // remove connection Nodes->removeRef(pn2); // delete node 2 if open pn2 = pn; } @@ -728,16 +750,16 @@ int Schematic::insertWire(Wire *w) if((pw->x1 != pn->cx) || (pw->y1 != pn->cy)) { nw = new Wire(pw->x1, pw->y1, pn->cx, pn->cy, pw->Port1, pn); - pn->Connections.append(nw); + pn->connect(nw); Wires->append(nw); Wires->findRef(pw); - pw->Port1->Connections.append(nw); + pw->Port1->connect(nw); } - pw->Port1->Connections.removeRef(pw); + pw->Port1->disconnect(pw); pw->x1 = pn2->cx; pw->y1 = pn2->cy; pw->Port1 = pn2; - pn2->Connections.append(pw); + pn2->connect(pw); pn = Nodes->next(); } @@ -752,10 +774,9 @@ int Schematic::insertWire(Wire *w) void Schematic::selectWireLine(Element *pe, Node *pn, bool ctrl) { Node *pn_1st = pn; - while(pn->Connections.count() == 2) + while(pn->conn_count() == 2) { - if(pn->Connections.first() == pe) pe = pn->Connections.last(); - else pe = pn->Connections.first(); + pe = pn->other_than(pe); if(pe->Type != isWire) break; if(ctrl) pe->isSelected ^= ctrl; @@ -788,10 +809,10 @@ Wire* Schematic::splitWire(Wire *pw, Node *pn) pw->y2 = pn->cy; pw->Port2 = pn; - newWire->Port2->Connections.prepend(newWire); - pn->Connections.prepend(pw); - pn->Connections.prepend(newWire); - newWire->Port2->Connections.removeRef(pw); + newWire->Port2->connect(newWire); + pn->connect(pw); + pn->connect(newWire); + newWire->Port2->disconnect(pw); Wires->append(newWire); if(pw->Label) @@ -810,8 +831,8 @@ Wire* Schematic::splitWire(Wire *pw, Node *pn) bool Schematic::oneTwoWires(Node *n) { Wire *e3; - Wire *e1 = (Wire*)n->Connections.getFirst(); // two wires -> one wire - Wire *e2 = (Wire*)n->Connections.getLast(); + Wire *e1 = (Wire*)n->any(); // two wires -> one wire + Wire *e2 = (Wire*)n->other_than(e1); if(e1->Type == isWire) if(e2->Type == isWire) if(e1->isHorizontal() == e2->isHorizontal()) @@ -841,8 +862,8 @@ bool Schematic::oneTwoWires(Node *n) e1->y2 = e2->y2; e1->Port2 = e2->Port2; Nodes->removeRef(n); // delete node (is auto delete) - e1->Port2->Connections.removeRef(e2); - e1->Port2->Connections.append(e1); + e1->Port2->disconnect(e2); + e1->Port2->connect(e1); Wires->removeRef(e2); return true; } @@ -853,27 +874,27 @@ bool Schematic::oneTwoWires(Node *n) // Deletes the wire 'w'. void Schematic::deleteWire(Wire *w) { - if(w->Port1->Connections.count() == 1) + if(w->Port1->conn_count() == 1) { if(w->Port1->Label) delete w->Port1->Label; Nodes->removeRef(w->Port1); // delete node 1 if open } else { - w->Port1->Connections.removeRef(w); // remove connection - if(w->Port1->Connections.count() == 2) + w->Port1->disconnect(w); // remove connection + if(w->Port1->conn_count() == 2) oneTwoWires(w->Port1); // two wires -> one wire } - if(w->Port2->Connections.count() == 1) + if(w->Port2->conn_count() == 1) { if(w->Port2->Label) delete w->Port2->Label; Nodes->removeRef(w->Port2); // delete node 2 if open } else { - w->Port2->Connections.removeRef(w); // remove connection - if(w->Port2->Connections.count() == 2) + w->Port2->disconnect(w); // remove connection + if(w->Port2->conn_count() == 2) oneTwoWires(w->Port2); // two wires -> one wire } @@ -907,7 +928,7 @@ int Schematic::copyWires(int& x1, int& y1, int& x2, int& y2, // rescue non-selected node labels pn = pw->Port1; if(pn->Label) - if(pn->Connections.count() < 2) + if(pn->conn_count() < 2) { ElementCache->append(pn->Label); @@ -918,7 +939,7 @@ int Schematic::copyWires(int& x1, int& y1, int& x2, int& y2, } pn = pw->Port2; if(pn->Label) - if(pn->Connections.count() < 2) + if(pn->conn_count() < 2) { ElementCache->append(pn->Label); @@ -1650,11 +1671,16 @@ void Schematic::newMovingWires(Q3PtrList *p, Node *pn, int pos) const if(pn->State & 16) // node was already worked on break; - pe = pn->Connections.getFirst(); - if(pe == 0) return; + if (pn->conn_count() == 0) { + return; + } - if(pn->Connections.count() > 1) + if(pn->conn_count() > 1) { break; + } + + pe = pn->any(); + if(pe->Type != isWire) // is it connected to exactly one wire ? break; @@ -1665,11 +1691,10 @@ void Schematic::newMovingWires(Q3PtrList *p, Node *pn, int pos) const Node *pn2 = pw->Port1; if(pn2 == pn) pn2 = pw->Port2; - if(pn2->Connections.count() == 2) // two existing wires connected ? + if(pn2->conn_count() == 2) // two existing wires connected ? if((pn2->State & (8+4)) == 0) { - Element *pe2 = pn2->Connections.getFirst(); - if(pe2 == pe) pe2 = pn2->Connections.getLast(); + Element *pe2 = pn2->other_than(pe); // connected wire connected to exactly one wire ? if(pe2->Type == isWire) pw2 = (Wire*)pe2; @@ -1678,9 +1703,9 @@ void Schematic::newMovingWires(Q3PtrList *p, Node *pn, int pos) const // ................................................. // reuse one wire p->insert(pos, pw); - pw->Port1->Connections.removeRef(pw); // remove connection 1 + pw->Port1->disconnect(pw); // remove connection 1 pw->Port1->State |= 16+4; - pw->Port2->Connections.removeRef(pw); // remove connection 2 + pw->Port2->disconnect(pw); // remove connection 2 pw->Port2->State |= 16+4; Wires->take(Wires->findRef(pw)); @@ -1726,9 +1751,9 @@ void Schematic::newMovingWires(Q3PtrList *p, Node *pn, int pos) const // ................................................. // reuse a second wire p->insert(pos, pw2); - pw2->Port1->Connections.removeRef(pw2); // remove connection 1 + pw2->Port1->disconnect(pw2); // remove connection 1 pw2->Port1->State |= 16+4; - pw2->Port2->Connections.removeRef(pw2); // remove connection 2 + pw2->Port2->disconnect(pw2); // remove connection 2 pw2->Port2->State |= 16+4; Wires->take(Wires->findRef(pw2)); @@ -1780,7 +1805,7 @@ int Schematic::copySelectedElements(Q3PtrList *p) // delete all port connections for (Port *pp : pc->Ports) { - pp->Connection->Connections.removeRef((Element*)pc); + pp->Connection->disconnect((Element*)pc); pp->Connection->State = 4; } @@ -1799,9 +1824,9 @@ int Schematic::copySelectedElements(Q3PtrList *p) { p->append(pw); - pw->Port1->Connections.removeRef(pw); // remove connection 1 + pw->Port1->disconnect(pw); // remove connection 1 pw->Port1->State = 4; - pw->Port2->Connections.removeRef(pw); // remove connection 2 + pw->Port2->disconnect(pw); // remove connection 2 pw->Port2->State = 4; Wires->take(); pw = Wires->current(); @@ -1841,14 +1866,14 @@ int Schematic::copySelectedElements(Q3PtrList *p) for(pn = Nodes->first(); pn!=0; ) { if(pn->State & 8) - if(pn->Connections.count() == 2) + if(pn->conn_count() == 2) if(oneTwoWires(pn)) // if possible, connect two wires to one { pn = Nodes->current(); continue; } - if(pn->Connections.count() == 0) + if(pn->conn_count() == 0) { if(pn->Label) { @@ -2522,8 +2547,7 @@ void Schematic::insertComponentNodes(Component *c, bool noOptimize) if(noOptimize) return; Node *pn; - Element *pe, *pe1; - Q3PtrList *pL; + Node* pL; // if component over wire then delete this wire QListIterator iport(c->Ports); // omit the first element @@ -2532,13 +2556,17 @@ void Schematic::insertComponentNodes(Component *c, bool noOptimize) { pp = iport.next(); pn = pp->Connection; - for(pe = pn->Connections.first(); pe!=0; pe = pn->Connections.next()) + for(auto* pe : *pn) if(pe->Type == isWire) { - if(((Wire*)pe)->Port1 == pn) pL = &(((Wire*)pe)->Port2->Connections); - else pL = &(((Wire*)pe)->Port1->Connections); + if (((Wire*)pe)->Port1 == pn) { + pL = ((Wire*)pe)->Port2; + } + else { + pL = ((Wire*)pe)->Port1; + } - for(pe1 = pL->first(); pe1!=0; pe1 = pL->next()) + for(auto* pe1 : *pL) if(pe1 == c) { deleteWire((Wire*)pe); @@ -2583,7 +2611,7 @@ void Schematic::recreateComponent(Component *Comp) // Otherwise the label would be deleted. pl = plMem = (WireLabel**)malloc(PortCount * sizeof(WireLabel*)); for (Port *pp : Comp->Ports) - if(pp->Connection->Connections.count() < 2) + if(pp->Connection->conn_count() < 2) { *(pl++) = pp->Connection->Label; pp->Connection->Label = 0; @@ -2788,8 +2816,8 @@ void Schematic::setCompPorts(Component *pc) for (Port *pp : pc->Ports) { - pp->Connection->Connections.removeRef((Element*)pc);// delete connections - switch(pp->Connection->Connections.count()) + pp->Connection->disconnect((Element*)pc);// delete connections + switch(pp->Connection->conn_count()) { case 0: pl = pp->Connection->Label; @@ -2876,7 +2904,7 @@ void Schematic::deleteComp(Component *c) { // delete all port connections for (Port *pn : c->Ports) - switch(pn->Connection->Connections.count()) + switch(pn->Connection->conn_count()) { case 1 : delete pn->Connection->Label; @@ -2884,11 +2912,11 @@ void Schematic::deleteComp(Component *c) pn->Connection = 0; // (auto-delete) break; case 3 : - pn->Connection->Connections.removeRef(c);// delete connection + pn->Connection->disconnect(c);// delete connection oneTwoWires(pn->Connection); // two wires -> one wire break; default : - pn->Connection->Connections.removeRef(c);// remove connection + pn->Connection->disconnect(c);// remove connection break; } emit signalComponentDeleted(c); @@ -2928,7 +2956,7 @@ int Schematic::copyComponents(int& x1, int& y1, int& x2, int& y2, // rescue non-selected node labels for (Port *pp : pc->Ports) if(pp->Connection->Label) - if(pp->Connection->Connections.count() < 2) + if(pp->Connection->conn_count() < 2) { ElementCache->append(pp->Connection->Label); @@ -2970,7 +2998,7 @@ void Schematic::copyComponents2(int& x1, int& y1, int& x2, int& y2, // rescue non-selected node labels for (Port *pp : pc->Ports) if(pp->Connection->Label) - if(pp->Connection->Connections.count() < 2) + if(pp->Connection->conn_count() < 2) { ElementCache->append(pp->Connection->Label); pp->Connection->Label = 0; @@ -2999,7 +3027,6 @@ void Schematic::oneLabel(Node *n1) { Wire *pw; Node *pn, *pNode; - Element *pe; WireLabel *pl = 0; bool named=false; // wire line already named ? Q3PtrList Cons; @@ -3025,7 +3052,7 @@ void Schematic::oneLabel(Node *n1) } } - for(pe = pn->Connections.first(); pe!=0; pe = pn->Connections.next()) + for(auto* pe : *pn) { if(pe->Type != isWire) { @@ -3108,7 +3135,6 @@ Element* Schematic::getWireLabel(Node *pn_) { Wire *pw; Node *pn, *pNode; - Element *pe; Q3PtrList Cons; for(pn = Nodes->first(); pn!=0; pn = Nodes->next()) @@ -3119,7 +3145,7 @@ Element* Schematic::getWireLabel(Node *pn_) for(pn = Cons.first(); pn!=0; pn = Cons.next()) if(pn->Label) return pn; else - for(pe = pn->Connections.first(); pe!=0; pe = pn->Connections.next()) + for(auto* pe : *pn) { if(pe->Type != isWire) { diff --git a/qucs/schematic_file.cpp b/qucs/schematic_file.cpp index 416eac840..798fb316f 100644 --- a/qucs/schematic_file.cpp +++ b/qucs/schematic_file.cpp @@ -851,7 +851,7 @@ void Schematic::simpleInsertComponent(Component *c) pn = new Node(x, y); DocNodes.append(pn); } - pn->Connections.append(c); // connect schematic node to component node + pn->connect(c); // connect schematic node to component node if (!pp->Type.isEmpty()) { pn->DType = pp->Type; } @@ -915,7 +915,7 @@ void Schematic::simpleInsertWire(Wire *pw) delete pw; // delete wire because this is not a wire return; } - pn->Connections.append(pw); // connect schematic node to component node + pn->connect(pw); // connect schematic node to component node pw->Port1 = pn; // check if second wire node lies upon existing node @@ -926,7 +926,7 @@ void Schematic::simpleInsertWire(Wire *pw) pn = new Node(pw->x2, pw->y2); DocNodes.append(pn); } - pn->Connections.append(pw); // connect schematic node to component node + pn->connect(pw); // connect schematic node to component node pw->Port2 = pn; DocWires.append(pw); @@ -1400,7 +1400,7 @@ void Schematic::propagateNode(QStringList& Collect, Cons.append(pn); for(p2 = Cons.first(); p2 != 0; p2 = Cons.next()) - for(pe = p2->Connections.first(); pe != 0; pe = p2->Connections.next()) + for(auto* pe : *p2) if(pe->Type == isWire) { pw = (Wire*)pe; if(p2 != pw->Port1) { diff --git a/qucs/wire.h b/qucs/wire.h index 457c0ad5f..d831a52d0 100644 --- a/qucs/wire.h +++ b/qucs/wire.h @@ -18,8 +18,7 @@ #ifndef WIRE_H #define WIRE_H -#include "element.h" -#include "components/component.h" // because of struct Port +#include "conductor.h" #include "wirelabel.h" class Schematic; diff --git a/qucs/wirelabel.h b/qucs/wirelabel.h index bfad2e239..c9546d9dd 100644 --- a/qucs/wirelabel.h +++ b/qucs/wirelabel.h @@ -18,13 +18,11 @@ #ifndef WIRELABEL_H #define WIRELABEL_H -#include "element.h" +#include "conductor.h" #include class QPainter; -class Wire; -class Node; class WireLabel : public Element {