Skip to content

Commit

Permalink
Merge pull request #878 from wawuwo/refactor-schematic-select-elements
Browse files Browse the repository at this point in the history
Refactor Schematic::selectElements
  • Loading branch information
ra3xdh committed Aug 3, 2024
2 parents bd210e9 + e371830 commit 0c72efe
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 90 deletions.
3 changes: 2 additions & 1 deletion qucs/mouseactions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1737,7 +1737,8 @@ void MouseActions::MReleaseSelect2(Schematic *Doc, QMouseEvent *Event)
bool IsShift = Event->modifiers().testFlag(Qt::ShiftModifier);

// selects all elements within the rectangle
Doc->selectElements(MAx1, MAy1, MAx1 + MAx2, MAy1 + MAy2, IsCtrl, !IsShift);
Doc->selectElements(
QRect{MAx1, MAy1, MAx2, MAy2}.normalized(), IsCtrl, !IsShift);

Doc->releaseKeyboard(); // allow keyboard inputs again
QucsMain->MouseMoveAction = 0;
Expand Down
2 changes: 1 addition & 1 deletion qucs/qucs_actions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -664,7 +664,7 @@ void QucsApp::slotSelectAll()
}
else {
auto selectionRect = ((Schematic*)Doc)->allBoundingRect().marginsAdded(QMargins{1, 1, 1, 1});
((Schematic*)Doc)->selectElements(selectionRect.left(), selectionRect.top(), selectionRect.right(), selectionRect.bottom(), true, false);
((Schematic*)Doc)->selectElements(selectionRect, true, false);
((Schematic*)Doc)->viewport()->update();
}
}
Expand Down
2 changes: 1 addition & 1 deletion qucs/schematic.h
Original file line number Diff line number Diff line change
Expand Up @@ -401,7 +401,7 @@ protected slots:

Element* selectElement(float, float, bool, int *index=0);
void deselectElements(Element*) const;
int selectElements(int, int, int, int, bool, bool) const;
int selectElements(const QRect&, bool, bool) const;
void selectMarkers() const;
void newMovingWires(Q3PtrList<Element>*, Node*, int) const;
int copySelectedElements(Q3PtrList<Element>*);
Expand Down
144 changes: 57 additions & 87 deletions qucs/schematic_element.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1521,126 +1521,96 @@ void Schematic::deselectElements(Element *e) const
if(e != pp) pp->isSelected = false;
}

// ---------------------------------------------------
// Selects elements that lie within the rectangle x1/y1, x2/y2.
int Schematic::selectElements(int x1, int y1, int x2, int y2, bool append, bool entirely) const {
int z = 0; // counts selected elements
int cx1, cy1, cx2, cy2;
// Selects elements that lie within or intersect with the rectangle selectionRect
int Schematic::selectElements(const QRect& selection_rect, bool append, bool entirely) const {
int selected_count = 0;
int left, top, right, bottom;

// exchange rectangle coordinates to obtain x1 < x2 and y1 < y2
cx1 = (x1 < x2) ? x1 : x2;
cx2 = (x1 >= x2) ? x1 : x2;
cy1 = (y1 < y2) ? y1 : y2;
cy2 = (y1 >= y2) ? y1 : y2;
x1 = cx1;
x2 = cx2;
y1 = cy1;
y2 = cy2;
auto select_element = [=](Element* e, const QRect& ebr) {
// If an element lies within selection rect, it must be selected regardless of any
// conditions
if (shouldBeSelected(ebr, selection_rect, entirely)) {
e->isSelected = true;
}
// If an element is not within selection rectangle, but it is already selected and we're
// not appending to a list of selected items, then the element must be deselected.
else if (e->isSelected && !append) {
e->isSelected = false;
}

QRect selectionRect(cx1, cy1, cx2 - cx1, cy2 - cy1);
return e->isSelected;
};

// test all components
for (Component *pc = Components->first(); pc != nullptr; pc = Components->next()) {
pc->Bounding(cx1, cy1, cx2, cy2);
QRect componentRect(cx1, cy1, cx2 - cx1, cy2 - cy1);
if (shouldBeSelected(componentRect, selectionRect, entirely)) {
pc->isSelected = true;
z++;
continue;
for (Component *component : *Components) {
component->Bounding(left, top, right, bottom);

if (select_element(component, QRect{left, top, right - left, bottom - top})) {
selected_count++;
}
if (pc->isSelected &= append) z++;
}


Wire *pw;
for (pw = Wires->first(); pw != nullptr; pw = Wires->next()) // test all wires
for (Wire* wire : *Wires)
{
QRect componentRect(pw->x1, pw->y1, pw->x2 - pw->x1, pw->y2 - pw->y1);
if (shouldBeSelected(componentRect, selectionRect, entirely)) {
pw->isSelected = true;
z++;
continue;
if (select_element(wire, QRect{wire->x1, wire->y1, wire->x2 - wire->x1, wire->y2 - wire->y1})) {
selected_count++;
}
if (pw->isSelected &= append) z++;
}

WireLabel *label = nullptr;
for (Wire* wire : *Wires) {
if (wire->Label) {
label = wire->Label;
label->getLabelBounding(left,top,right,bottom);

// test all wire labels *********************************
WireLabel *pl = nullptr;
for (pw = Wires->first(); pw != nullptr; pw = Wires->next()) {
if (pw->Label) {
pl = pw->Label;
pl->getLabelBounding(cx1,cy1,cx2,cy2);
QRect componentRect(cx1, cy1, cx2 - cx1, cy2 - cy1);
if (shouldBeSelected(componentRect, selectionRect, entirely)) {
pl->isSelected = true;
z++;
continue;
if (select_element(label, QRect{left, top, right - left, bottom - top})) {
selected_count++;
}
if (pl->isSelected &= append) z++;
}
}

for (Node *node : *Nodes) {
label = node->Label;
if (label) {
label->getLabelBounding(left,top,right,bottom);

// test all node labels *************************************
for (Node *pn = Nodes->first(); pn != nullptr; pn = Nodes->next()) {
pl = pn->Label;
if (pl) {
pl->getLabelBounding(cx1,cy1,cx2,cy2);
QRect componentRect(cx1, cy1, cx2 - cx1, cy2 - cy1);
if (shouldBeSelected(componentRect, selectionRect, entirely)) {
pl->isSelected = true;
z++;
continue;
if (select_element(label, QRect{left, top, right - left, bottom - top})) {
selected_count++;
}
if (pl->isSelected &= append) z++;
}
}

for (Diagram *diagram : *Diagrams) {
for (Graph *graph: diagram->Graphs) {
if (graph->isSelected &= append) {
selected_count++;
}

// test all diagrams *******************************************
for (Diagram *pd = Diagrams->first(); pd != 0; pd = Diagrams->next()) {
// test graphs of diagram
for (Graph *pg: pd->Graphs) {
if (pg->isSelected &= append) z++;
for (Marker *marker: graph->Markers) {
marker->Bounding(left, top, right, bottom);

// test markers of graph
for (Marker *pm: pg->Markers) {
pm->Bounding(cx1, cy1, cx2, cy2);
QRect componentRect(cx1, cy1, cx2 - cx1, cy2 - cy1);
if (shouldBeSelected(componentRect, selectionRect, entirely)) {
pm->isSelected = true;
z++;
continue;
if (select_element(marker, QRect{left, top, right - left, bottom - top})) {
selected_count++;
}
if (pm->isSelected &= append) z++;
}
}

// test diagram itself
pd->Bounding(cx1, cy1, cx2, cy2);
QRect componentRect(cx1, cy1, cx2 - cx1, cy2 - cy1);
if (shouldBeSelected(componentRect, selectionRect, entirely)) {
pd->isSelected = true;
z++;
continue;
diagram->Bounding(left, top, right, bottom);

if (select_element(diagram, QRect{left, top, right - left, bottom - top})) {
selected_count++;
}
if (pd->isSelected &= append) z++;
}

// test all paintings *******************************************
for (Painting *pp = Paintings->first(); pp != 0; pp = Paintings->next()) {
pp->Bounding(cx1, cy1, cx2, cy2);
QRect componentRect(cx1, cy1, cx2 - cx1, cy2 - cy1);
if (shouldBeSelected(componentRect, selectionRect, entirely)) {
pp->isSelected = true;
z++;
continue;
for (Painting *painting : *Paintings) {
painting->Bounding(left, top, right, bottom);

if (select_element(painting, QRect{left, top, right - left, bottom - top})) {
selected_count++;
}
if (pp->isSelected &= append) z++;
}

return z;
return selected_count;
}

// ---------------------------------------------------
Expand Down

0 comments on commit 0c72efe

Please sign in to comment.