diff --git a/qucs/imagewriter.cpp b/qucs/imagewriter.cpp index 61be3b1f9..5b5138549 100644 --- a/qucs/imagewriter.cpp +++ b/qucs/imagewriter.cpp @@ -124,7 +124,7 @@ int ImageWriter::print(QWidget *doc) int h = all.height(); - QRect selected = sch->sizeOfSelection(); + QRect selected = sch->currentSelection().bounds; int wsel = selected.width(); int hsel = selected.height(); diff --git a/qucs/schematic.cpp b/qucs/schematic.cpp index 7a604cfc2..efa6e40c7 100644 --- a/qucs/schematic.cpp +++ b/qucs/schematic.cpp @@ -749,7 +749,7 @@ void Schematic::print(QPrinter*, QPainter* painter, bool printAll, const QRectF pageSize{0, 0, static_cast(painter->device()->width()), static_cast(painter->device()->height())}; - QRect printedArea = printAll ? allBoundingRect() : sizeOfSelection(); + QRect printedArea = printAll ? allBoundingRect() : currentSelection().bounds; if (printAll && a_showFrame) { int frame_width, frame_height; @@ -977,7 +977,7 @@ void Schematic::zoomToSelection() { return; } - const QRect selectedBoundingRect{ sizeOfSelection() }; + const QRect selectedBoundingRect{ currentSelection().bounds }; // Working with raw coordinates is clumsy, abstract them out const QRect usedBoundingRect{a_UsedX1, a_UsedY1, a_UsedX2 - a_UsedX1, a_UsedY2 - a_UsedY1}; @@ -1280,7 +1280,7 @@ void Schematic::sizeOfAll(int &xmin, int &ymin, int &xmax, int &ymax) } } -QRect Schematic::sizeOfSelection() const { +Schematic::Selection Schematic::currentSelection() const { int xmin = INT_MAX; int ymin = INT_MAX; int xmax = INT_MIN; @@ -1290,9 +1290,11 @@ QRect Schematic::sizeOfSelection() const { if (a_Components->isEmpty() && a_Wires->isEmpty() && a_Diagrams->isEmpty() && a_Paintings->isEmpty()) { - return QRect{}; + return {}; } + Selection selection; + int x1, y1, x2, y2; // find boundings of all components for (auto* pc : *a_Components) { @@ -1300,6 +1302,7 @@ QRect Schematic::sizeOfSelection() const { continue; } isAnySelected = true; + selection.components.push_back(pc); pc->entireBounds(x1, y1, x2, y2); xmin = std::min(x1, xmin); xmax = std::max(x2, xmax); @@ -1313,12 +1316,14 @@ QRect Schematic::sizeOfSelection() const { continue; } isAnySelected = true; + selection.wires.push_back(pw); xmin = std::min(pw->x1, xmin); xmax = std::max(pw->x2, xmax); ymin = std::min(pw->y1, ymin); ymax = std::max(pw->y2, ymax); if (auto* pl = pw->Label; pl) { // check position of wire label + selection.labels.push_back(pl); pl->getLabelBounding(x1, y1, x2, y2); xmin = std::min(x1, xmin); xmax = std::max(x2, xmax); @@ -1329,11 +1334,12 @@ QRect Schematic::sizeOfSelection() const { // find boundings of all node labels for (auto* pn : *a_Nodes) { - if (!pn->isSelected) { - continue; + if (std::all_of(pn->begin(), pn->end(), [](auto* e) { return e->isSelected; })) { + selection.nodes.push_back(pn); } if (auto* pl = pn->Label; pl) { // check position of node label + selection.labels.push_back(pl); isAnySelected = true; pl->getLabelBounding(x1, y1, x2, y2); xmin = std::min(x1, xmin); @@ -1348,6 +1354,7 @@ QRect Schematic::sizeOfSelection() const { if (!pd->isSelected) { continue; } + selection.diagrams.push_back(pd); isAnySelected = true; pd->Bounding(x1, y1, x2, y2); xmin = std::min(x1, xmin); @@ -1358,6 +1365,7 @@ QRect Schematic::sizeOfSelection() const { for (Graph* pg : pd->Graphs) { // test all markers of diagram for (Marker* pm : pg->Markers) { + selection.markers.push_back(pm); pm->Bounding(x1, y1, x2, y2); xmin = std::min(x1, xmin); xmax = std::max(x2, xmax); @@ -1372,6 +1380,7 @@ QRect Schematic::sizeOfSelection() const { if (!pp->isSelected) { continue; } + selection.paintings.push_back(pp); isAnySelected = true; pp->Bounding(x1, y1, x2, y2); xmin = std::min(x1, xmin); @@ -1381,10 +1390,11 @@ QRect Schematic::sizeOfSelection() const { } if (!isAnySelected) { - return QRect{}; + return {}; } - return QRect{xmin, ymin, xmax - xmin, ymax - ymin}; + selection.bounds = QRect{xmin, ymin, xmax - xmin, ymax - ymin}; + return selection; } // --------------------------------------------------- diff --git a/qucs/schematic.h b/qucs/schematic.h index 95daa0414..5d54cbc56 100644 --- a/qucs/schematic.h +++ b/qucs/schematic.h @@ -103,7 +103,19 @@ class Schematic : public Q3ScrollView, public QucsDoc { Returns the smallest rectangle enclosing all elements of schematic */ QRect allBoundingRect(); - QRect sizeOfSelection() const; + + struct Selection { + QRect bounds; + std::vector components; + std::vector wires; + std::vector paintings; + std::vector diagrams; + std::vector labels; + std::vector markers; + std::vector nodes; + }; + + Selection currentSelection() const; bool rotateElements(); bool mirrorXComponents(); bool mirrorYComponents(); diff --git a/qucs/schematic_element.cpp b/qucs/schematic_element.cpp index e19925550..b689673bb 100644 --- a/qucs/schematic_element.cpp +++ b/qucs/schematic_element.cpp @@ -1484,41 +1484,19 @@ void Schematic::highlightWireLabels () // Deselects all elements except 'e'. void Schematic::deselectElements(Element *e) const { - // test all components - for(Component *pc = a_Components->first(); pc != 0; pc = a_Components->next()) - if(e != pc) pc->isSelected = false; - - // test all wires - for(Wire *pw = a_Wires->first(); pw != 0; pw = a_Wires->next()) - { - if(e != pw) pw->isSelected = false; - if(pw->Label) if(pw->Label != e) pw->Label->isSelected = false; - } - - // test all node labels - for(Node *pn = a_Nodes->first(); pn != 0; pn = a_Nodes->next()) - if(pn->Label) if(pn->Label != e) pn->Label->isSelected = false; - - // test all diagrams - for(Diagram *pd = a_Diagrams->first(); pd != 0; pd = a_Diagrams->next()) - { - if(e != pd) pd->isSelected = false; - - // test graphs of diagram - for (Graph *pg : pd->Graphs) - { - if(e != pg) pg->isSelected = false; + Selection selection = currentSelection(); + auto deselector = [e](auto* elem) { elem->isSelected = elem == e; }; - // test markers of graph - for (Marker *pm : pg->Markers) - if(e != pm) pm->isSelected = false; - } + std::for_each(selection.components.begin(), selection.components.end(), deselector); + std::for_each(selection.wires.begin(), selection.wires.end(), deselector); + std::for_each(selection.paintings.begin(), selection.paintings.end(), deselector); + std::for_each(selection.diagrams.begin(), selection.diagrams.end(), deselector); + std::for_each(selection.labels.begin(), selection.labels.end(), deselector); + std::for_each(selection.markers.begin(), selection.markers.end(), deselector); + for(auto* pd : *a_Diagrams) { + std::for_each(pd->Graphs.begin(), pd->Graphs.end(), deselector); } - - // test all paintings - for(Painting *pp = a_Paintings->first(); pp != 0; pp = a_Paintings->next()) - if(e != pp) pp->isSelected = false; } // Selects elements that lie within or intersect with the rectangle selectionRect @@ -1982,47 +1960,25 @@ int Schematic::copyElements(int& x1, int& y1, int& x2, int& y2, bool Schematic::deleteElements() { bool sel = false; + auto selection = currentSelection(); - Component *pc = a_Components->first(); - while(pc != 0) // all selected component - if(pc->isSelected) - { + for (auto* pc : selection.components) { // all selected component deleteComp(pc); - pc = a_Components->current(); sel = true; - } - else pc = a_Components->next(); + } - Wire *pw = a_Wires->first(); - while(pw != 0) // all selected wires and their labels - { - if(pw->Label) - if(pw->Label->isSelected) - { - delete pw->Label; - pw->Label = 0; - sel = true; - } + for (auto* l : selection.labels) { + l->pOwner->Label = nullptr; + delete l; + } - if(pw->isSelected) - { + for (auto* pw : selection.wires) // all selected wires + { deleteWire(pw); pw = a_Wires->current(); sel = true; - } - else pw = a_Wires->next(); } - // all selected labels on nodes *************************** - for(Node *pn = a_Nodes->first(); pn != 0; pn = a_Nodes->next()) - if(pn->Label) - if(pn->Label->isSelected) - { - delete pn->Label; - pn->Label = 0; - sel = true; - } - Diagram *pd = a_Diagrams->first(); while(pd != 0) // test all diagrams if(pd->isSelected) @@ -2067,11 +2023,8 @@ bool Schematic::deleteElements() pd = a_Diagrams->next(); } //else - - Painting *pp = a_Paintings->first(); - while(pp != 0) // test all paintings + for (auto* pp : selection.paintings) // test all paintings { - if(pp->isSelected) { // Allow removing of manually inserted port symbols when in symbol // editing mode. If port symbol is inserted manually i.e. doesn't // have a corresponding port in schematic, its nameStr is empty. @@ -2079,20 +2032,16 @@ bool Schematic::deleteElements() // must have found a pairing port in schematic. if (pp->Name.trimmed() == ".PortSym" && a_isSymbolOnly) { sel = true; - a_Paintings->remove(); - pp = a_Paintings->current(); + a_Paintings->remove(pp); continue; } if(pp->Name.at(0) != '.') // do not delete "PortSym", "ID_text" { sel = true; - a_Paintings->remove(); - pp = a_Paintings->current(); + a_Paintings->remove(pp); continue; } - } - pp = a_Paintings->next(); } if(sel) @@ -2763,9 +2712,8 @@ bool Schematic::activateSelectedComponents() { int a; bool sel = false; - for(Component *pc = a_Components->first(); pc != 0; pc = a_Components->next()) - if(pc->isSelected) - { + + for (auto* pc : currentSelection().components) { a = pc->isActive - 1; if(pc->Ports.count() > 1) @@ -2854,10 +2802,9 @@ Component* Schematic::selectCompText(int x_, int y_, int& w, int& h) const Component* Schematic::searchSelSubcircuit() { Component *sub=0; - // test all components - for(Component *pc = a_Components->first(); pc != 0; pc = a_Components->next()) + + for(auto* pc : currentSelection().components) { - if(!pc->isSelected) continue; if(pc->Model != "Sub") if(pc->Model != "VHDL") if(pc->Model != "Verilog") continue; @@ -2918,13 +2865,10 @@ Component *Schematic::getComponentByName(const QString& compname) const int Schematic::copyComponents(int& x1, int& y1, int& x2, int& y2, QList *ElementCache) { - Component *pc; int bx1, by1, bx2, by2, count=0; // find bounds of all selected components - for(pc = a_Components->first(); pc != 0; ) + for (auto* pc : currentSelection().components) { - if(pc->isSelected) - { pc->Bounding(bx1, by1, bx2, by2); // is needed because of "distribute if(bx1 < x1) x1 = bx1; // uniformly" if(bx2 > x2) x2 = bx2; @@ -2950,10 +2894,6 @@ int Schematic::copyComponents(int& x1, int& y1, int& x2, int& y2, } deleteComp(pc); - pc = a_Components->current(); - continue; - } - pc = a_Components->next(); } return count; } @@ -2962,12 +2902,9 @@ int Schematic::copyComponents(int& x1, int& y1, int& x2, int& y2, void Schematic::copyComponents2(int& x1, int& y1, int& x2, int& y2, QList *ElementCache) { - Component *pc; // find bounds of all selected components - for(pc = a_Components->first(); pc != 0; ) + for (auto* pc : currentSelection().components) { - if(pc->isSelected) - { // is better for unsymmetrical components if(pc->cx < x1) x1 = pc->cx; if(pc->cx > x2) x2 = pc->cx; @@ -2988,10 +2925,6 @@ void Schematic::copyComponents2(int& x1, int& y1, int& x2, int& y2, } deleteComp(pc); - pc = a_Components->current(); - continue; - } - pc = a_Components->next(); } } @@ -3181,34 +3114,14 @@ void Schematic::insertNodeLabel(WireLabel *pl) void Schematic::copyLabels(int& x1, int& y1, int& x2, int& y2, QList *ElementCache) { - WireLabel *pl; - // find bounds of all selected wires - for(Wire *pw = a_Wires->first(); pw != 0; pw = a_Wires->next()) + // find bounds of all selected labels + for (auto* pl : currentSelection().labels) { - pl = pw->Label; - if(pl) if(pl->isSelected) - { if(pl->x1 < x1) x1 = pl->x1; if(pl->y1-pl->y2 < y1) y1 = pl->y1-pl->y2; if(pl->x1+pl->x2 > x2) x2 = pl->x1+pl->x2; if(pl->y1 > y2) y2 = pl->y1; ElementCache->append(pl); - } - } - - for(Node *pn = a_Nodes->first(); pn != 0; pn = a_Nodes->next()) - { - pl = pn->Label; - if(pl) if(pl->isSelected) - { - if(pl->x1 < x1) x1 = pl->x1; - if(pl->y1-pl->y2 < y1) y1 = pl->y1-pl->y2; - if(pl->x1+pl->x2 > x2) x2 = pl->x1+pl->x2; - if(pl->y1 > y2) y2 = pl->y1; - ElementCache->append(pl); - pl->pOwner->Label = 0; // erase connection - pl->pOwner = 0; - } } } @@ -3234,11 +3147,9 @@ Painting* Schematic::selectedPainting(float fX, float fY) void Schematic::copyPaintings(int& x1, int& y1, int& x2, int& y2, QList *ElementCache) { - Painting *pp; int bx1, by1, bx2, by2; // find boundings of all selected paintings - for(pp = a_Paintings->first(); pp != 0; ) - if(pp->isSelected) + for (auto* pp : currentSelection().paintings) { pp->Bounding(bx1, by1, bx2, by2); if(bx1 < x1) x1 = bx1; @@ -3247,10 +3158,8 @@ void Schematic::copyPaintings(int& x1, int& y1, int& x2, int& y2, if(by2 > y2) y2 = by2; ElementCache->append(pp); - a_Paintings->take(); - pp = a_Paintings->current(); + a_Paintings->take(a_Paintings->find(pp)); } - else pp = a_Paintings->next(); } // vim:ts=8:sw=2:noet