From 8fd9c1901366c1a2c7a2d6ed9a36ddd3ae68f992 Mon Sep 17 00:00:00 2001 From: Ajinkya Dahale Date: Thu, 23 Jan 2025 17:23:39 +0530 Subject: [PATCH] [Sketcher] Refactor `TaskSketcherElements::onSelectionChanged()` --- src/Mod/Sketcher/Gui/TaskSketcherElements.cpp | 256 +++++++++--------- 1 file changed, 134 insertions(+), 122 deletions(-) diff --git a/src/Mod/Sketcher/Gui/TaskSketcherElements.cpp b/src/Mod/Sketcher/Gui/TaskSketcherElements.cpp index 95be1ebbea..8191548e30 100644 --- a/src/Mod/Sketcher/Gui/TaskSketcherElements.cpp +++ b/src/Mod/Sketcher/Gui/TaskSketcherElements.cpp @@ -1400,138 +1400,150 @@ void TaskSketcherElements::updateVisibility() } /*------------------*/ +// clang-format on void TaskSketcherElements::onSelectionChanged(const Gui::SelectionChanges& msg) { - std::string temp; - if (msg.Type == Gui::SelectionChanges::ClrSelection) { - clearWidget(); - } - else if (msg.Type == Gui::SelectionChanges::AddSelection - || msg.Type == Gui::SelectionChanges::RmvSelection) { - bool select = (msg.Type == Gui::SelectionChanges::AddSelection); - // is it this object?? - if (strcmp(msg.pDocName, sketchView->getSketchObject()->getDocument()->getName()) == 0 - && strcmp(msg.pObjectName, sketchView->getSketchObject()->getNameInDocument()) == 0) { - if (msg.pSubName) { - ElementItem* modified_item = NULL; - QString expr = QString::fromLatin1(msg.pSubName); - std::string shapetype(msg.pSubName); - // if-else edge vertex - if (shapetype.size() > 4 && shapetype.substr(0, 4) == "Edge") { - QRegularExpression rx(QStringLiteral("^Edge(\\d+)$")); - QRegularExpressionMatch match; - boost::ignore_unused(expr.indexOf(rx, 0, &match)); - if (match.hasMatch()) { - bool ok; - int ElementId = match.captured(1).toInt(&ok) - 1; - if (ok) { - int countItems = ui->listWidgetElements->count(); - // TODO: This and the loop below get slow when we have a lot of items. - // Perhaps we should also maintain a map so that we can look up items - // by element number. - for (int i = 0; i < countItems; i++) { - ElementItem* item = - static_cast(ui->listWidgetElements->item(i)); - if (item->ElementNbr == ElementId) { - item->isLineSelected = select; - modified_item = item; - SketcherGui::scrollTo(ui->listWidgetElements, i, select); - break; - } - } - } - } - } - else if (shapetype.size() > 12 && shapetype.substr(0, 12) == "ExternalEdge") { - QRegularExpression rx(QStringLiteral("^ExternalEdge(\\d+)$")); - QRegularExpressionMatch match; - boost::ignore_unused(expr.indexOf(rx, 0, &match)); - if (match.hasMatch()) { - bool ok; - int ElementId = -match.captured(1).toInt(&ok) - 2; - if (ok) { - int countItems = ui->listWidgetElements->count(); - for (int i = 0; i < countItems; i++) { - ElementItem* item = - static_cast(ui->listWidgetElements->item(i)); - if (item->ElementNbr == ElementId) { - item->isLineSelected = select; - modified_item = item; - break; - } - } - } - } - } - else if (shapetype.size() > 6 && shapetype.substr(0, 6) == "Vertex") { - QRegularExpression rx(QStringLiteral("^Vertex(\\d+)$")); - QRegularExpressionMatch match; - boost::ignore_unused(expr.indexOf(rx, 0, &match)); - if (match.hasMatch()) { - bool ok; - int ElementId = match.captured(1).toInt(&ok) - 1; - if (ok) { - // Get the GeoID&Pos - int GeoId; - Sketcher::PointPos PosId; - sketchView->getSketchObject()->getGeoVertexIndex( - ElementId, GeoId, PosId); + // update the listwidget + auto updateListWidget = [this](auto& modified_item) { + QSignalBlocker sigblk(this->ui->listWidgetElements); + if (modified_item == nullptr) { + return; + } + bool is_selected = modified_item->isSelected(); + const bool should_be_selected = modified_item->isLineSelected + || modified_item->isStartingPointSelected || modified_item->isEndPointSelected + || modified_item->isMidPointSelected; - int countItems = ui->listWidgetElements->count(); - for (int i = 0; i < countItems; i++) { - ElementItem* item = - static_cast(ui->listWidgetElements->item(i)); - if (item->ElementNbr == GeoId) { - modified_item = item; - switch (PosId) { - case Sketcher::PointPos::start: - item->isStartingPointSelected = select; - break; - case Sketcher::PointPos::end: - item->isEndPointSelected = select; - break; - case Sketcher::PointPos::mid: - item->isMidPointSelected = select; - break; - default: - break; - } - break; - } - } - } - } + // If an element is already selected and a new subelement gets selected + // (eg., if you select the arc of a circle then select the center as + // well), the new subelement won't get highlighted in the list until you + // mouseover the list. To avoid this, we deselect first to trigger a + // redraw. + if (should_be_selected && is_selected) { + modified_item->setSelected(false); + is_selected = false; + } + + if (should_be_selected != is_selected) { + modified_item->setSelected(should_be_selected); + } + }; + + switch (msg.Type) { + case Gui::SelectionChanges::ClrSelection: { + clearWidget(); + return; + } + case Gui::SelectionChanges::AddSelection: + case Gui::SelectionChanges::RmvSelection: { + bool select = (msg.Type == Gui::SelectionChanges::AddSelection); + // is it this object?? + if (strcmp(msg.pDocName, sketchView->getSketchObject()->getDocument()->getName()) != 0 + || strcmp(msg.pObjectName, sketchView->getSketchObject()->getNameInDocument()) + != 0) { + return; + } + if (!msg.pSubName) { + return; + } + ElementItem* modified_item = nullptr; + QString expr = QString::fromLatin1(msg.pSubName); + std::string shapetype(msg.pSubName); + // if-else edge vertex + if (boost::starts_with(shapetype, "Edge")) { + QRegularExpression rx(QStringLiteral("^Edge(\\d+)$")); + QRegularExpressionMatch match; + boost::ignore_unused(expr.indexOf(rx, 0, &match)); + if (!match.hasMatch()) { + return; } - // update the listwidget - { - QSignalBlocker sigblk(ui->listWidgetElements); - if (modified_item != NULL) { - bool is_selected = modified_item->isSelected(); - const bool should_be_selected = modified_item->isLineSelected - || modified_item->isStartingPointSelected || modified_item->isEndPointSelected - || modified_item->isMidPointSelected; - - // If an element is already selected and a new subelement gets selected - // (eg., if you select the arc of a circle then select the center as well), - // the new subelement won't get highlighted in the list until you mouseover - // the list. To avoid this, we deselect first to trigger a redraw. - if (should_be_selected && is_selected) { - modified_item->setSelected(false); - is_selected = false; - } - - if (should_be_selected != is_selected) { - modified_item->setSelected(should_be_selected); - } + bool ok; + int ElementId = match.captured(1).toInt(&ok) - 1; + if (!ok) { + return; + } + int countItems = ui->listWidgetElements->count(); + // TODO: This and the loop below get slow when we have a lot of items. + // Perhaps we should also maintain a map so that we can look up items + // by element number. + for (int i = 0; i < countItems; i++) { + ElementItem* item = static_cast(ui->listWidgetElements->item(i)); + if (item->ElementNbr == ElementId) { + item->isLineSelected = select; + modified_item = item; + SketcherGui::scrollTo(ui->listWidgetElements, i, select); + break; } } } + else if (boost::starts_with(shapetype, "ExternalEdge")) { + QRegularExpression rx(QStringLiteral("^ExternalEdge(\\d+)$")); + QRegularExpressionMatch match; + boost::ignore_unused(expr.indexOf(rx, 0, &match)); + if (!match.hasMatch()) { + return; + } + bool ok; + int ElementId = -match.captured(1).toInt(&ok) - 2; + if (!ok) { + return; + } + int countItems = ui->listWidgetElements->count(); + for (int i = 0; i < countItems; i++) { + ElementItem* item = static_cast(ui->listWidgetElements->item(i)); + if (item->ElementNbr == ElementId) { + item->isLineSelected = select; + modified_item = item; + break; + } + } + } + else if (boost::starts_with(shapetype, "Vertex")) { + QRegularExpression rx(QStringLiteral("^Vertex(\\d+)$")); + QRegularExpressionMatch match; + boost::ignore_unused(expr.indexOf(rx, 0, &match)); + if (!match.hasMatch()) { + return; + } + bool ok; + int ElementId = match.captured(1).toInt(&ok) - 1; + if (!ok) { + return; + } + // Get the GeoID&Pos + int GeoId; + Sketcher::PointPos PosId; + sketchView->getSketchObject()->getGeoVertexIndex(ElementId, GeoId, PosId); + + int countItems = ui->listWidgetElements->count(); + for (int i = 0; i < countItems; i++) { + ElementItem* item = static_cast(ui->listWidgetElements->item(i)); + if (item->ElementNbr == GeoId) { + modified_item = item; + switch (PosId) { + case Sketcher::PointPos::start: + item->isStartingPointSelected = select; + break; + case Sketcher::PointPos::end: + item->isEndPointSelected = select; + break; + case Sketcher::PointPos::mid: + item->isMidPointSelected = select; + break; + default: + break; + } + break; + } + } + } + updateListWidget(modified_item); } - } - else if (msg.Type == Gui::SelectionChanges::SetSelection) { - // do nothing here + default: + return; } } +// clang-format off void TaskSketcherElements::onListWidgetElementsItemPressed(QListWidgetItem* it) {