[Sketcher] Refactor TaskSketcherElements::onSelectionChanged()

This commit is contained in:
Ajinkya Dahale
2025-01-23 17:23:39 +05:30
committed by Benjamin Nauck
parent ace0c57dd6
commit 8fd9c19013

View File

@@ -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<ElementItem*>(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<ElementItem*>(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<ElementItem*>(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<ElementItem*>(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<ElementItem*>(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<ElementItem*>(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)
{