Download src/Gui/Dialogs/DlgObjectSelection.cpp from AbdulElahGwaith/FreeCAD: direct link, hf CLI and curl.
- Browser
- Download file 25.7 kB
-
https://huggingface.co/AbdulElahGwaith/FreeCAD/resolve/main/src/Gui/Dialogs/DlgObjectSelection.cpp
- Command line
-
hf download hf://AbdulElahGwaith/FreeCAD/src/Gui/Dialogs/DlgObjectSelection.cpp
-
curl -L -o DlgObjectSelection.cpp https://huggingface.co/AbdulElahGwaith/FreeCAD/resolve/main/src/Gui/Dialogs/DlgObjectSelection.cpp
25.7 kB
| // SPDX-License-Identifier: LGPL-2.1-or-later | |
| /**************************************************************************** | |
| * Copyright (c) 2018 Zheng Lei (realthunder) <realthunder.dev@gmail.com> * | |
| * * | |
| * This file is part of the FreeCAD CAx development system. * | |
| * * | |
| * This library is free software; you can redistribute it and/or * | |
| * modify it under the terms of the GNU Library General Public * | |
| * License as published by the Free Software Foundation; either * | |
| * version 2 of the License, or (at your option) any later version. * | |
| * * | |
| * This library is distributed in the hope that it will be useful, * | |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of * | |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * | |
| * GNU Library General Public License for more details. * | |
| * * | |
| * You should have received a copy of the GNU Library General Public * | |
| * License along with this library; see the file COPYING.LIB. If not, * | |
| * write to the Free Software Foundation, Inc., 59 Temple Place, * | |
| * Suite 330, Boston, MA 02111-1307, USA * | |
| * * | |
| ****************************************************************************/ | |
| FC_LOG_LEVEL_INIT("Gui", true, true) | |
| using namespace Gui; | |
| /* TRANSLATOR Gui::DlgObjectSelection */ | |
| DlgObjectSelection::DlgObjectSelection( | |
| const std::vector<App::DocumentObject*>& objs, | |
| QWidget* parent, | |
| Qt::WindowFlags fl | |
| ) | |
| : QDialog(parent, fl) | |
| { | |
| init(objs, {}); | |
| } | |
| DlgObjectSelection::DlgObjectSelection( | |
| const std::vector<App::DocumentObject*>& objs, | |
| const std::vector<App::DocumentObject*>& excludes, | |
| QWidget* parent, | |
| Qt::WindowFlags fl | |
| ) | |
| : QDialog(parent, fl) | |
| { | |
| init(objs, excludes); | |
| } | |
| static bool inline setCheckState(QTreeWidgetItem* item, Qt::CheckState state, bool forced = true) | |
| { | |
| if (!forced) { | |
| if (item->isSelected()) { | |
| if (state == Qt::Unchecked || item->checkState(0) == Qt::Unchecked) { | |
| return false; | |
| } | |
| } | |
| if (item->checkState(0) == state) { | |
| return false; | |
| } | |
| } | |
| // auto objT = qvariant_cast<App::SubObjectT>(item->data(0, Qt::UserRole)); | |
| // FC_MSG(objT.getObjectFullName() << (state == Qt::Unchecked ? " unchecked" : | |
| // (state == Qt::Checked ? " checked" : " partial"))); | |
| item->setCheckState(0, state); | |
| return true; | |
| } | |
| void DlgObjectSelection::init( | |
| const std::vector<App::DocumentObject*>& objs, | |
| const std::vector<App::DocumentObject*>& excludes | |
| ) | |
| { | |
| initSels = objs; | |
| std::sort(initSels.begin(), initSels.end()); | |
| deps = App::Document::getDependencyList(objs, App::Document::DepSort); | |
| depSet.insert(deps.begin(), deps.end()); | |
| ui = new Ui_DlgObjectSelection; | |
| ui->setupUi(this); | |
| hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/General"); | |
| ui->checkBoxAutoDeps->setChecked(hGrp->GetBool("ObjectSelectionAutoDeps", true)); | |
| connect(ui->checkBoxAutoDeps, &QCheckBox::toggled, this, &DlgObjectSelection::onAutoDeps); | |
| ui->checkBoxShowDeps->setChecked(hGrp->GetBool("ObjectSelectionShowDeps", false)); | |
| QObject::connect(ui->checkBoxShowDeps, &QCheckBox::toggled, [this](bool checked) { | |
| hGrp->SetBool("ObjectSelectionShowDeps", checked); | |
| onShowDeps(); | |
| }); | |
| QMetaObject::invokeMethod(this, "onShowDeps", Qt::QueuedConnection); | |
| // make sure to show a horizontal scrollbar if needed | |
| ui->depList->header()->setSectionResizeMode(0, QHeaderView::ResizeToContents); | |
| ui->depList->header()->setSectionResizeMode(1, QHeaderView::ResizeToContents); | |
| ui->depList->header()->setSectionResizeMode(2, QHeaderView::ResizeToContents); | |
| ui->inList->header()->setSectionResizeMode(0, QHeaderView::ResizeToContents); | |
| ui->inList->header()->setSectionResizeMode(1, QHeaderView::ResizeToContents); | |
| ui->inList->header()->setSectionResizeMode(2, QHeaderView::ResizeToContents); | |
| ui->treeWidget->header()->setSectionResizeMode(0, QHeaderView::ResizeToContents); | |
| ui->depList->headerItem()->setText(0, tr("Depending on")); | |
| ui->depList->headerItem()->setText(1, tr("Document")); | |
| ui->depList->headerItem()->setText(2, tr("Name")); | |
| ui->inList->headerItem()->setText(0, tr("Depended by")); | |
| ui->inList->headerItem()->setText(1, tr("Document")); | |
| ui->inList->headerItem()->setText(2, tr("Name")); | |
| ui->treeWidget->headerItem()->setText(0, tr("Selections")); | |
| ui->treeWidget->header()->setStretchLastSection(false); | |
| connect(ui->treeWidget, &QTreeWidget::itemExpanded, this, &DlgObjectSelection::onItemExpanded); | |
| allItem = new QTreeWidgetItem(ui->treeWidget); | |
| allItem->setText(0, QStringLiteral("<%1>").arg(tr("All"))); | |
| QFont font = allItem->font(0); | |
| font.setBold(true); | |
| allItem->setFont(0, font); | |
| allItem->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled); | |
| allItem->setCheckState(0, Qt::Checked); | |
| for (auto obj : initSels) { | |
| getItem(obj)->setCheckState(0, Qt::Checked); | |
| } | |
| for (auto obj : deps) { | |
| getItem(obj)->setCheckState(0, Qt::Checked); | |
| } | |
| auto filter = excludes; | |
| std::sort(filter.begin(), filter.end()); | |
| for (auto obj : deps) { | |
| auto it = std::lower_bound(filter.begin(), filter.end(), obj); | |
| if (it != filter.end() && *it == obj) { | |
| setItemState(obj, Qt::Unchecked); | |
| } | |
| } | |
| onItemSelectionChanged(); | |
| /** | |
| * create useOriginalsBtn and add to the button box | |
| * tried adding to .ui file, but could never get the | |
| * formatting exactly the way I wanted it. -- <TheMarkster> | |
| */ | |
| useOriginalsBtn = new QPushButton(tr("&Use Original Selection")); | |
| useOriginalsBtn->setToolTip( | |
| tr("Ignore dependencies and proceed with the objects\noriginally selected prior to opening " | |
| "this dialog") | |
| ); | |
| ui->buttonBox->addButton(useOriginalsBtn, QDialogButtonBox::ResetRole); | |
| connect(ui->treeWidget, &QTreeWidget::itemChanged, this, &DlgObjectSelection::onObjItemChanged); | |
| connect(ui->depList, &QTreeWidget::itemChanged, this, &DlgObjectSelection::onDepItemChanged); | |
| connect(ui->inList, &QTreeWidget::itemChanged, this, &DlgObjectSelection::onDepItemChanged); | |
| connect( | |
| ui->treeWidget, | |
| &QTreeWidget::itemSelectionChanged, | |
| this, | |
| &DlgObjectSelection::onItemSelectionChanged | |
| ); | |
| connect(useOriginalsBtn, &QPushButton::clicked, this, &DlgObjectSelection::onUseOriginalsBtnClicked); | |
| connect(ui->buttonBox, &QDialogButtonBox::accepted, this, &DlgObjectSelection::accept); | |
| connect(ui->buttonBox, &QDialogButtonBox::rejected, this, &DlgObjectSelection::reject); | |
| timer.setSingleShot(true); | |
| connect(&timer, &QTimer::timeout, this, &DlgObjectSelection::checkItemChanged); | |
| } | |
| /** | |
| * Destroys the object and frees any allocated resources | |
| */ | |
| DlgObjectSelection::~DlgObjectSelection() | |
| { | |
| // no need to delete child widgets, Qt does it all for us | |
| delete ui; | |
| } | |
| QTreeWidgetItem* DlgObjectSelection::getItem( | |
| App::DocumentObject* obj, | |
| std::vector<QTreeWidgetItem*>** pitems, | |
| QTreeWidgetItem* parent | |
| ) | |
| { | |
| auto& items = itemMap[App::SubObjectT(obj, "")]; | |
| if (pitems) { | |
| *pitems = &items; | |
| } | |
| QTreeWidgetItem* item; | |
| if (!parent) { | |
| if (!items.empty()) { | |
| return items[0]; | |
| } | |
| item = new QTreeWidgetItem(ui->treeWidget); | |
| auto vp = freecad_cast<ViewProviderDocumentObject*>( | |
| Gui::Application::Instance->getViewProvider(obj) | |
| ); | |
| if (vp) { | |
| item->setIcon(0, vp->getIcon()); | |
| } | |
| App::SubObjectT objT(obj, ""); | |
| item->setText(0, QString::fromUtf8((obj)->Label.getValue())); | |
| if (std::binary_search(initSels.begin(), initSels.end(), obj)) { | |
| QFont font = item->font(0); | |
| font.setBold(true); | |
| font.setItalic(true); | |
| item->setFont(0, font); | |
| } | |
| item->setToolTip(0, QString::fromUtf8(objT.getObjectFullName().c_str())); | |
| item->setData(0, Qt::UserRole, QVariant::fromValue(objT)); | |
| item->setChildIndicatorPolicy( | |
| obj->getOutList().empty() ? QTreeWidgetItem::DontShowIndicator | |
| : QTreeWidgetItem::ShowIndicator | |
| ); | |
| } | |
| else if (!items.empty()) { | |
| item = new QTreeWidgetItem(parent); | |
| item->setIcon(0, items[0]->icon(0)); | |
| item->setText(0, items[0]->text(0)); | |
| item->setFont(0, items[0]->font(0)); | |
| item->setToolTip(0, items[0]->toolTip(0)); | |
| item->setData(0, Qt::UserRole, items[0]->data(0, Qt::UserRole)); | |
| item->setChildIndicatorPolicy(items[0]->childIndicatorPolicy()); | |
| item->setCheckState(0, items[0]->checkState(0)); | |
| } | |
| else { | |
| return nullptr; | |
| } | |
| items.push_back(item); | |
| item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsUserCheckable | Qt::ItemIsEnabled); | |
| return item; | |
| } | |
| void DlgObjectSelection::onItemExpanded(QTreeWidgetItem* item) | |
| { | |
| if (item->childCount()) { | |
| return; | |
| } | |
| if (auto obj = qvariant_cast<App::SubObjectT>(item->data(0, Qt::UserRole)).getObject()) { | |
| QSignalBlocker blocker(ui->treeWidget); | |
| std::set<App::DocumentObject*> set; | |
| for (auto child : obj->getOutList()) { | |
| if (child && set.insert(child).second) { | |
| getItem(child, nullptr, item); | |
| } | |
| } | |
| } | |
| } | |
| void DlgObjectSelection::updateAllItemState() | |
| { | |
| int count = 0; | |
| for (const auto& v : itemMap) { | |
| auto state = v.second[0]->checkState(0); | |
| if (state == Qt::Unchecked) { | |
| if (count) { | |
| allItem->setCheckState(0, Qt::PartiallyChecked); | |
| return; | |
| } | |
| } | |
| else { | |
| if (state == Qt::PartiallyChecked) { | |
| allItem->setCheckState(0, Qt::PartiallyChecked); | |
| return; | |
| } | |
| ++count; | |
| } | |
| } | |
| if (count && count == (int)itemMap.size()) { | |
| allItem->setCheckState(0, Qt::Checked); | |
| } | |
| else if (!count) { | |
| allItem->setCheckState(0, Qt::Unchecked); | |
| } | |
| } | |
| void DlgObjectSelection::setItemState(App::DocumentObject* obj, Qt::CheckState state, bool forced) | |
| { | |
| std::vector<QTreeWidgetItem*>* items = nullptr; | |
| auto item = getItem(obj, &items); | |
| if (!setCheckState(item, state, forced)) { | |
| return; | |
| } | |
| for (size_t i = 1; i < items->size(); ++i) { | |
| setCheckState(items->at(i), state, true); | |
| } | |
| std::vector<App::DocumentObject*> objs = {obj}; | |
| if (ui->checkBoxAutoDeps->isChecked() && state == Qt::Checked) { | |
| // If an object is newly checked, check all its dependencies | |
| for (auto o : obj->getOutListRecursive()) { | |
| if (!depSet.contains(o) || itemChanged.contains(o)) { | |
| continue; | |
| } | |
| auto itItem = itemMap.find(o); | |
| if (itItem == itemMap.end() || itItem->second[0]->checkState(0) == state) { | |
| continue; | |
| } | |
| for (auto i : itItem->second) { | |
| setCheckState(i, state, true); | |
| } | |
| objs.push_back(o); | |
| } | |
| } | |
| for (auto obj : objs) { | |
| auto it = inMap.find(obj); | |
| if (it != inMap.end()) { | |
| setCheckState(it->second, state); | |
| } | |
| auto itDep = depMap.find(obj); | |
| if (itDep != depMap.end()) { | |
| setCheckState(itDep->second, state); | |
| } | |
| // If an object toggles state, we need to revisit all its in-list | |
| // object to update the partial/full checked state. | |
| for (auto o : obj->getInList()) { | |
| if (!depSet.contains(o) || itemChanged.contains(o)) { | |
| continue; | |
| } | |
| auto it = itemMap.find(o); | |
| if (it == itemMap.end() || it->second[0]->checkState(0) == state) { | |
| continue; | |
| } | |
| int count = 0; | |
| int selcount = 0; | |
| for (auto sibling : o->getOutList()) { | |
| if (!depSet.contains(sibling)) { | |
| continue; | |
| } | |
| ++count; | |
| auto it = itemMap.find(sibling); | |
| if (it == itemMap.end()) { | |
| continue; | |
| } | |
| auto s = it->second[0]->checkState(0); | |
| if (s == Qt::Unchecked) { | |
| continue; | |
| } | |
| if (it->second[0]->checkState(0) == Qt::PartiallyChecked) { | |
| selcount = -1; | |
| break; | |
| } | |
| ++selcount; | |
| } | |
| auto state = it->second[0]->checkState(0); | |
| if (state == Qt::Checked && selcount != count) { | |
| setItemState(o, Qt::PartiallyChecked, true); | |
| } | |
| else if (state == Qt::PartiallyChecked && selcount == count) { | |
| setItemState(o, Qt::Checked, true); | |
| } | |
| } | |
| } | |
| } | |
| std::vector<App::DocumentObject*> DlgObjectSelection::getSelections(SelectionOptions options) const | |
| { | |
| if (returnOriginals) { | |
| return initSels; | |
| } | |
| std::vector<App::DocumentObject*> res; | |
| Base::Flags<SelectionOptions> flags(options); | |
| if (!flags.testFlag(SelectionOptions::Invert)) { | |
| for (const auto& v : itemMap) { | |
| if (v.second[0]->checkState(0) == Qt::Unchecked) { | |
| continue; | |
| } | |
| if (auto obj = v.first.getObject()) { | |
| res.push_back(obj); | |
| } | |
| } | |
| } | |
| else { | |
| for (auto obj : deps) { | |
| auto it = itemMap.find(obj); | |
| if (it == itemMap.end() || it->second[0]->checkState(0) == Qt::Unchecked) { | |
| res.push_back(obj); | |
| } | |
| } | |
| } | |
| if (flags.testFlag(SelectionOptions::Sort)) { | |
| std::sort(res.begin(), res.end()); | |
| } | |
| return res; | |
| } | |
| void DlgObjectSelection::onDepItemChanged(QTreeWidgetItem* depItem, int column) | |
| { | |
| if (column) { | |
| return; | |
| } | |
| QSignalBlocker blocker(ui->depList); | |
| QSignalBlocker blocker2(ui->inList); | |
| QSignalBlocker blocker3(ui->treeWidget); | |
| auto state = depItem->checkState(0); | |
| if (depItem->isSelected()) { | |
| const auto items = depItem->treeWidget()->selectedItems(); | |
| for (auto item : items) { | |
| auto objT = qvariant_cast<App::SubObjectT>(item->data(0, Qt::UserRole)); | |
| auto it = itemMap.find(objT); | |
| if (it == itemMap.end()) { | |
| continue; | |
| } | |
| setCheckState(item, state); | |
| for (auto i : it->second) { | |
| setCheckState(i, state); | |
| } | |
| itemChanged[objT] = state; | |
| } | |
| } | |
| else { | |
| auto objT = qvariant_cast<App::SubObjectT>(depItem->data(0, Qt::UserRole)); | |
| auto it = itemMap.find(objT); | |
| if (it != itemMap.end()) { | |
| itemChanged[objT] = state; | |
| for (auto i : it->second) { | |
| setCheckState(i, state); | |
| } | |
| } | |
| } | |
| timer.start(10); | |
| } | |
| void DlgObjectSelection::onObjItemChanged(QTreeWidgetItem* objItem, int column) | |
| { | |
| if (column != 0) { | |
| return; | |
| } | |
| QSignalBlocker blocker3(ui->treeWidget); | |
| auto state = objItem->checkState(0); | |
| if (objItem == allItem) { | |
| if (state == Qt::PartiallyChecked) { | |
| return; | |
| } | |
| ui->treeWidget->selectionModel()->clearSelection(); | |
| itemChanged.clear(); | |
| timer.stop(); | |
| onItemSelectionChanged(); | |
| if (state == Qt::Unchecked) { | |
| for (const auto& v : itemMap) { | |
| for (auto i : v.second) { | |
| setCheckState(i, Qt::Unchecked); | |
| } | |
| auto it = depMap.find(v.first); | |
| if (it != depMap.end()) { | |
| setCheckState(it->second, Qt::Unchecked); | |
| } | |
| it = inMap.find(v.first); | |
| if (it != inMap.end()) { | |
| setCheckState(it->second, Qt::Unchecked); | |
| } | |
| } | |
| } | |
| else { | |
| for (auto obj : initSels) { | |
| setCheckState(getItem(obj), Qt::Checked); | |
| } | |
| for (auto obj : deps) { | |
| setCheckState(getItem(obj), Qt::Checked); | |
| auto it = depMap.find(obj); | |
| if (it != depMap.end()) { | |
| setCheckState(it->second, Qt::Checked); | |
| } | |
| it = inMap.find(obj); | |
| if (it != inMap.end()) { | |
| setCheckState(it->second, Qt::Checked); | |
| } | |
| } | |
| } | |
| return; | |
| } | |
| if (!objItem->isSelected()) { | |
| ui->treeWidget->selectionModel()->clearSelection(); | |
| objItem->setSelected(true); | |
| // We treat selected item in tree widget specially in case of checking | |
| // items in depList or inList. To simplify logic, we change selection | |
| // here if an unselected item has been checked. | |
| itemChanged[qvariant_cast<App::SubObjectT>(objItem->data(0, Qt::UserRole))] = state; | |
| onItemSelectionChanged(); | |
| } | |
| else { | |
| const auto items = ui->treeWidget->selectedItems(); | |
| for (auto item : items) { | |
| setCheckState(item, state); | |
| itemChanged[qvariant_cast<App::SubObjectT>(item->data(0, Qt::UserRole))] = state; | |
| } | |
| } | |
| timer.start(10); | |
| } | |
| static bool getOutList( | |
| App::DocumentObject* obj, | |
| std::set<App::DocumentObject*>& visited, | |
| std::vector<App::DocumentObject*>& result | |
| ) | |
| { | |
| if (!visited.insert(obj).second) { | |
| return false; | |
| } | |
| for (auto o : obj->getOutList()) { | |
| if (getOutList(o, visited, result)) { | |
| result.push_back(o); | |
| } | |
| } | |
| return true; | |
| } | |
| void DlgObjectSelection::checkItemChanged() | |
| { | |
| QSignalBlocker blocker(ui->depList); | |
| QSignalBlocker blocker2(ui->inList); | |
| QSignalBlocker blocker3(ui->treeWidget); | |
| std::set<App::DocumentObject*> unchecked; | |
| for (const auto& v : itemChanged) { | |
| const auto& objT = v.first; | |
| Qt::CheckState state = v.second; | |
| if (auto obj = objT.getObject()) { | |
| if (state == Qt::Unchecked) { | |
| // We'll deal with unchecked item later | |
| if (ui->checkBoxAutoDeps->isChecked()) { | |
| unchecked.insert(obj); | |
| } | |
| } | |
| else { | |
| // For checked item, setItemState will auto select its | |
| // dependency | |
| setItemState(obj, state, true); | |
| } | |
| } | |
| } | |
| if (!unchecked.empty()) { | |
| // When some item is unchecked by the user, we need to re-check the | |
| // recursive outlist of the initially selected object, excluding all | |
| // currently unchecked object. And then uncheck any item that does not | |
| // appear in the returned outlist. | |
| for (const auto& v : itemMap) { | |
| auto item = v.second[0]; | |
| if (item->checkState(0) == Qt::Unchecked) { | |
| if (auto obj = qvariant_cast<App::SubObjectT>(item->data(0, Qt::UserRole)).getObject()) { | |
| unchecked.insert(obj); | |
| } | |
| } | |
| } | |
| auto outlist = initSels; | |
| for (auto obj : initSels) { | |
| getOutList(obj, unchecked, outlist); | |
| } | |
| std::sort(outlist.begin(), outlist.end()); | |
| for (const auto& v : itemMap) { | |
| if (!itemChanged.contains(v.first) && v.second[0]->checkState(0) == Qt::Unchecked) { | |
| continue; | |
| } | |
| if (auto obj = v.first.getObject()) { | |
| if (!std::binary_search(outlist.begin(), outlist.end(), obj)) { | |
| setItemState(obj, Qt::Unchecked, true); | |
| } | |
| } | |
| } | |
| } | |
| itemChanged.clear(); | |
| updateAllItemState(); | |
| } | |
| QTreeWidgetItem* DlgObjectSelection::createDepItem(QTreeWidget* parent, App::DocumentObject* obj) | |
| { | |
| auto item = new QTreeWidgetItem(parent); | |
| if (parent == ui->depList) { | |
| depMap[obj] = item; | |
| } | |
| else { | |
| inMap[obj] = item; | |
| } | |
| App::SubObjectT objT(obj); | |
| auto vp = Gui::Application::Instance->getViewProvider(obj); | |
| if (vp) { | |
| item->setIcon(0, vp->getIcon()); | |
| } | |
| item->setData(0, Qt::UserRole, QVariant::fromValue(objT)); | |
| item->setToolTip(0, QString::fromUtf8(objT.getObjectFullName().c_str())); | |
| item->setText(0, QString::fromUtf8((obj)->Label.getValue())); | |
| if (std::binary_search(initSels.begin(), initSels.end(), obj)) { | |
| QFont font = item->font(0); | |
| font.setBold(true); | |
| font.setItalic(true); | |
| item->setFont(0, font); | |
| } | |
| item->setText(1, QString::fromUtf8(obj->getDocument()->getName())); | |
| item->setText(2, QString::fromUtf8(obj->getNameInDocument())); | |
| item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsUserCheckable | Qt::ItemIsEnabled); | |
| auto it = itemMap.find(obj); | |
| if (it != itemMap.end()) { | |
| setCheckState(item, it->second[0]->checkState(0)); | |
| } | |
| return item; | |
| } | |
| void DlgObjectSelection::onItemSelectionChanged() | |
| { | |
| ui->depList->clear(); | |
| depMap.clear(); | |
| ui->inList->clear(); | |
| inMap.clear(); | |
| std::vector<App::DocumentObject*> sels; | |
| const auto items = ui->treeWidget->selectedItems(); | |
| for (auto item : items) { | |
| if (item == allItem) { | |
| sels.clear(); | |
| break; | |
| } | |
| auto obj = qvariant_cast<App::SubObjectT>(item->data(0, Qt::UserRole)).getObject(); | |
| if (obj) { | |
| sels.push_back(obj); | |
| } | |
| } | |
| std::vector<App::DocumentObject*> _deps; | |
| if (!sels.empty()) { | |
| std::sort(sels.begin(), sels.end()); | |
| for (auto dep : App::Document::getDependencyList(sels, App::Document::DepSort)) { | |
| if (!std::binary_search(sels.begin(), sels.end(), dep)) { | |
| _deps.push_back(dep); | |
| } | |
| } | |
| } | |
| bool enabled = ui->depList->isSortingEnabled(); | |
| if (enabled) { | |
| ui->depList->setSortingEnabled(false); | |
| } | |
| bool enabled2 = ui->inList->isSortingEnabled(); | |
| if (enabled2) { | |
| ui->inList->setSortingEnabled(false); | |
| } | |
| { | |
| QSignalBlocker blocker(ui->depList); | |
| auto& objs = !sels.empty() ? _deps : deps; | |
| for (auto it = objs.rbegin(); it != objs.rend(); ++it) { | |
| createDepItem(ui->depList, *it); | |
| } | |
| } | |
| std::set<App::DocumentObject*> inlist; | |
| for (auto obj : sels) { | |
| obj->getInListEx(inlist, true); | |
| } | |
| for (auto it = inlist.begin(); it != inlist.end();) { | |
| if (!depSet.contains(*it) || std::binary_search(sels.begin(), sels.end(), *it)) { | |
| it = inlist.erase(it); | |
| } | |
| else { | |
| ++it; | |
| } | |
| } | |
| { | |
| QSignalBlocker blocker2(ui->inList); | |
| for (auto obj : inlist) { | |
| createDepItem(ui->inList, obj); | |
| } | |
| } | |
| if (enabled) { | |
| ui->depList->setSortingEnabled(true); | |
| } | |
| if (enabled2) { | |
| ui->inList->setSortingEnabled(true); | |
| } | |
| } | |
| void DlgObjectSelection::onUseOriginalsBtnClicked() | |
| { | |
| returnOriginals = true; | |
| QDialog::accept(); | |
| } | |
| void DlgObjectSelection::accept() | |
| { | |
| QDialog::accept(); | |
| } | |
| void DlgObjectSelection::reject() | |
| { | |
| QDialog::reject(); | |
| } | |
| void DlgObjectSelection::addCheckBox(QCheckBox* box) | |
| { | |
| ui->horizontalLayout->insertWidget(0, box); | |
| } | |
| void DlgObjectSelection::setMessage(const QString& msg) | |
| { | |
| ui->label->setText(msg); | |
| } | |
| void DlgObjectSelection::onAutoDeps(bool checked) | |
| { | |
| hGrp->SetBool("ObjectSelectionAutoDeps", checked); | |
| if (!checked) { | |
| return; | |
| } | |
| QSignalBlocker blocker(ui->treeWidget); | |
| for (auto obj : deps) { | |
| auto it = itemMap.find(obj); | |
| if (it == itemMap.end()) { | |
| continue; | |
| } | |
| auto item = it->second[0]; | |
| if (item->checkState(0) == Qt::Unchecked) { | |
| continue; | |
| } | |
| Qt::CheckState state = Qt::Checked; | |
| for (auto o : obj->getOutList()) { | |
| auto it = itemMap.find(o); | |
| if (it == itemMap.end()) { | |
| continue; | |
| } | |
| if (it->second[0]->checkState(0) != Qt::Checked) { | |
| state = Qt::PartiallyChecked; | |
| break; | |
| } | |
| } | |
| for (auto i : it->second) { | |
| setCheckState(i, state); | |
| } | |
| } | |
| onItemSelectionChanged(); | |
| } | |
| void DlgObjectSelection::onShowDeps() | |
| { | |
| bool checked = ui->checkBoxShowDeps->isChecked(); | |
| auto sizes = ui->vsplitter->sizes(); | |
| if (!checked && sizes[1] > 0) { | |
| sizes[1] = 0; | |
| } | |
| else if (checked && (sizes[0] == 0 || sizes[1] == 0)) { | |
| sizes[0] = sizes[1] = this->width() / 2; | |
| } | |
| else { | |
| return; | |
| } | |
| ui->vsplitter->setSizes(sizes); | |
| } | |