| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| |
|
| |
|
| | #include <QAction>
|
| | #include <QApplication>
|
| | #include <QKeyEvent>
|
| | #include <QListWidgetItem>
|
| | #include <QTimer>
|
| |
|
| |
|
| | #include <App/Application.h>
|
| | #include <App/Document.h>
|
| | #include <App/DocumentObject.h>
|
| | #include <Gui/BitmapFactory.h>
|
| | #include <Gui/Command.h>
|
| | #include <Gui/Selection/Selection.h>
|
| | #include <Gui/Tools.h>
|
| | #include <Gui/WaitCursor.h>
|
| | #include <Mod/PartDesign/App/Body.h>
|
| | #include <Mod/PartDesign/Gui/ReferenceSelection.h>
|
| |
|
| | #include "TaskDressUpParameters.h"
|
| |
|
| |
|
| | FC_LOG_LEVEL_INIT("PartDesign", true, true)
|
| |
|
| | using namespace PartDesignGui;
|
| | using namespace Gui;
|
| |
|
| |
|
| |
|
| |
|
| | TaskDressUpParameters::TaskDressUpParameters(
|
| | ViewProviderDressUp* DressUpView,
|
| | bool selectEdges,
|
| | bool selectFaces,
|
| | QWidget* parent
|
| | )
|
| | : TaskFeatureParameters(DressUpView, parent, DressUpView->featureIcon(), DressUpView->menuName)
|
| | , proxy(nullptr)
|
| | , deleteAction(nullptr)
|
| | , addAllEdgesAction(nullptr)
|
| | , allowFaces(selectFaces)
|
| | , allowEdges(selectEdges)
|
| | , DressUpView(DressUpView)
|
| | {
|
| |
|
| | App::GetApplication().getActiveTransaction(&transactionID);
|
| |
|
| | selectionMode = none;
|
| | }
|
| |
|
| | TaskDressUpParameters::~TaskDressUpParameters()
|
| | {
|
| |
|
| | Gui::Selection().rmvSelectionGate();
|
| | }
|
| |
|
| | void TaskDressUpParameters::setupTransaction()
|
| | {
|
| | if (DressUpView.expired()) {
|
| | return;
|
| | }
|
| |
|
| | int tid = 0;
|
| | App::GetApplication().getActiveTransaction(&tid);
|
| | if (tid && tid == transactionID) {
|
| | return;
|
| | }
|
| |
|
| |
|
| | std::string n("Edit ");
|
| | n += DressUpView->getObject()->Label.getValue();
|
| | transactionID = App::GetApplication().setActiveTransaction(n.c_str());
|
| | }
|
| |
|
| | void TaskDressUpParameters::referenceSelected(const Gui::SelectionChanges& msg, QListWidget* widget)
|
| | {
|
| | if (strcmp(msg.pDocName, DressUpView->getObject()->getDocument()->getName()) != 0) {
|
| | return;
|
| | }
|
| |
|
| | Gui::Selection().clearSelection();
|
| |
|
| | PartDesign::DressUp* pcDressUp = DressUpView->getObject<PartDesign::DressUp>();
|
| | App::DocumentObject* base = this->getBase();
|
| |
|
| |
|
| | const char* fname = base->getNameInDocument();
|
| | if (strcmp(msg.pObjectName, fname) != 0) {
|
| | return;
|
| | }
|
| |
|
| | const std::string subName(msg.pSubName);
|
| | std::vector<std::string> refs = pcDressUp->Base.getSubValues();
|
| |
|
| | if (const auto f = std::ranges::find(refs, subName); f != refs.end()) {
|
| | refs.erase(f);
|
| | removeItemFromListWidget(widget, msg.pSubName);
|
| | }
|
| | else {
|
| | refs.push_back(subName);
|
| | widget->addItem(QString::fromStdString(msg.pSubName));
|
| | }
|
| |
|
| | updateFeature(pcDressUp, refs);
|
| | }
|
| |
|
| | void TaskDressUpParameters::addAllEdges(QListWidget* widget)
|
| | {
|
| | Q_UNUSED(widget)
|
| |
|
| | if (DressUpView.expired()) {
|
| | return;
|
| | }
|
| |
|
| | PartDesign::DressUp* pcDressUp = DressUpView->getObject<PartDesign::DressUp>();
|
| | App::DocumentObject* base = pcDressUp->Base.getValue();
|
| | if (!base) {
|
| | return;
|
| | }
|
| | int count = Part::Feature::getTopoShape(
|
| | base,
|
| | Part::ShapeOption::ResolveLink | Part::ShapeOption::Transform
|
| | )
|
| | .countSubShapes(TopAbs_EDGE);
|
| | auto subValues = pcDressUp->Base.getSubValues(false);
|
| | std::size_t len = subValues.size();
|
| | for (int i = 0; i < count; ++i) {
|
| | std::string name = "Edge" + std::to_string(i + 1);
|
| | if (std::find(subValues.begin(), subValues.begin() + len, name) == subValues.begin() + len) {
|
| | subValues.push_back(name);
|
| | }
|
| | }
|
| | if (subValues.size() == len) {
|
| | return;
|
| | }
|
| | try {
|
| | setupTransaction();
|
| | pcDressUp->Base.setValue(base, subValues);
|
| | }
|
| | catch (Base::Exception& e) {
|
| | e.reportException();
|
| | }
|
| | }
|
| |
|
| | void TaskDressUpParameters::deleteRef(QListWidget* widget)
|
| | {
|
| |
|
| | Gui::Selection().clearSelection();
|
| |
|
| |
|
| | QList<QListWidgetItem*> selectedList = widget->selectedItems();
|
| |
|
| | PartDesign::DressUp* pcDressUp = DressUpView->getObject<PartDesign::DressUp>();
|
| | std::vector<std::string> refs = pcDressUp->Base.getSubValues();
|
| |
|
| |
|
| | QSignalBlocker block(widget);
|
| | for (int i = selectedList.count() - 1; i > -1; i--) {
|
| |
|
| |
|
| | int rowNumber = widget->row(selectedList.at(i));
|
| | refs.erase(refs.begin() + rowNumber);
|
| | widget->model()->removeRow(rowNumber);
|
| | }
|
| |
|
| | updateFeature(pcDressUp, refs);
|
| | }
|
| |
|
| | void TaskDressUpParameters::updateFeature(
|
| | PartDesign::DressUp* pcDressUp,
|
| | const std::vector<std::string>& refs
|
| | )
|
| | {
|
| | if (selectionMode == refSel) {
|
| | DressUpView->highlightReferences(false);
|
| | }
|
| |
|
| | setupTransaction();
|
| | pcDressUp->Base.setValue(pcDressUp->Base.getValue(), refs);
|
| | pcDressUp->recomputeFeature();
|
| | if (selectionMode == refSel) {
|
| | DressUpView->highlightReferences(true);
|
| | }
|
| | else {
|
| | hideOnError();
|
| | }
|
| | }
|
| |
|
| | void TaskDressUpParameters::onButtonRefSel(bool checked)
|
| | {
|
| | setSelectionMode(checked ? refSel : none);
|
| | }
|
| |
|
| | void TaskDressUpParameters::doubleClicked(QListWidgetItem* item)
|
| | {
|
| |
|
| |
|
| |
|
| | Q_UNUSED(item)
|
| | wasDoubleClicked = true;
|
| |
|
| |
|
| | setSelectionMode(none);
|
| |
|
| |
|
| | QTimer::singleShot(
|
| | QApplication::doubleClickInterval(),
|
| | this,
|
| | &TaskDressUpParameters::itemClickedTimeout
|
| | );
|
| | }
|
| |
|
| | void TaskDressUpParameters::setSelection(QListWidgetItem* current)
|
| | {
|
| |
|
| |
|
| |
|
| | if (current == nullptr) {
|
| | setSelectionMode(none);
|
| | return;
|
| | }
|
| |
|
| | if (!wasDoubleClicked) {
|
| |
|
| | QTimer::singleShot(
|
| | QApplication::doubleClickInterval(),
|
| | this,
|
| | &TaskDressUpParameters::itemClickedTimeout
|
| | );
|
| |
|
| |
|
| | std::string subName = current->text().toStdString();
|
| |
|
| | std::string docName = DressUpView->getObject()->getDocument()->getName();
|
| |
|
| | Part::BodyBase* body = PartDesign::Body::findBodyOf(DressUpView->getObject());
|
| | if (body) {
|
| | std::string objName = body->getNameInDocument();
|
| |
|
| |
|
| | if (selectionMode == none) {
|
| | setSelectionMode(refSel);
|
| | }
|
| | else {
|
| | Gui::Selection().clearSelection();
|
| | }
|
| |
|
| |
|
| | bool block = this->blockSelection(true);
|
| | tryAddSelection(docName, objName, subName);
|
| | this->blockSelection(block);
|
| | }
|
| | }
|
| | }
|
| |
|
| | void TaskDressUpParameters::tryAddSelection(
|
| | const std::string& doc,
|
| | const std::string& obj,
|
| | const std::string& sub
|
| | )
|
| | {
|
| | try {
|
| | Gui::Selection().addSelection(doc.c_str(), obj.c_str(), sub.c_str(), 0, 0, 0);
|
| | }
|
| | catch (const Base::Exception& e) {
|
| | e.reportException();
|
| | }
|
| | catch (const Standard_Failure& e) {
|
| | Base::Console().error("OCC error: %s\n", e.GetMessageString());
|
| | }
|
| | }
|
| |
|
| | QString TaskDressUpParameters::startSelectionLabel()
|
| | {
|
| | return tr("Select");
|
| | }
|
| |
|
| | QString TaskDressUpParameters::stopSelectionLabel()
|
| | {
|
| | return tr("Confirm Selection");
|
| | }
|
| |
|
| | void TaskDressUpParameters::itemClickedTimeout()
|
| | {
|
| |
|
| | wasDoubleClicked = false;
|
| | }
|
| |
|
| | void TaskDressUpParameters::createAddAllEdgesAction(QListWidget* parentList)
|
| | {
|
| |
|
| |
|
| | addAllEdgesAction = new QAction(tr("Add All Edges"), this);
|
| | addAllEdgesAction->setShortcut(QKeySequence(QStringLiteral("Ctrl+Shift+A")));
|
| |
|
| | addAllEdgesAction->setShortcutVisibleInContextMenu(true);
|
| | parentList->addAction(addAllEdgesAction);
|
| | addAllEdgesAction->setStatusTip(
|
| | tr("Adds all edges to the list box (only when in add selection mode)")
|
| | );
|
| | parentList->setContextMenuPolicy(Qt::ActionsContextMenu);
|
| | }
|
| |
|
| | void TaskDressUpParameters::createDeleteAction(QListWidget* parentList)
|
| | {
|
| |
|
| |
|
| | deleteAction = new QAction(tr("Remove"), this);
|
| | deleteAction->setShortcut(Gui::QtTools::deleteKeySequence());
|
| |
|
| |
|
| | deleteAction->setShortcutVisibleInContextMenu(true);
|
| | parentList->addAction(deleteAction);
|
| | parentList->setContextMenuPolicy(Qt::ActionsContextMenu);
|
| | }
|
| |
|
| | bool TaskDressUpParameters::event(QEvent* event)
|
| | {
|
| | if (event->type() == QEvent::ShortcutOverride) {
|
| | QKeyEvent* kevent = static_cast<QKeyEvent*>(event);
|
| | if (deleteAction && Gui::QtTools::matches(kevent, deleteAction->shortcut())) {
|
| | kevent->accept();
|
| | return true;
|
| | }
|
| | if (addAllEdgesAction && Gui::QtTools::matches(kevent, addAllEdgesAction->shortcut())) {
|
| | kevent->accept();
|
| | return true;
|
| | }
|
| | }
|
| |
|
| | return TaskBox::event(event);
|
| | }
|
| |
|
| | void TaskDressUpParameters::keyPressEvent(QKeyEvent* ke)
|
| | {
|
| | if (deleteAction && deleteAction->isEnabled()
|
| | && Gui::QtTools::matches(ke, deleteAction->shortcut())) {
|
| | deleteAction->trigger();
|
| | return;
|
| | }
|
| | if (addAllEdgesAction && addAllEdgesAction->isEnabled()
|
| | && Gui::QtTools::matches(ke, addAllEdgesAction->shortcut())) {
|
| | addAllEdgesAction->trigger();
|
| | return;
|
| | }
|
| |
|
| | TaskBox::keyPressEvent(ke);
|
| | }
|
| |
|
| | const std::vector<std::string> TaskDressUpParameters::getReferences() const
|
| | {
|
| | PartDesign::DressUp* pcDressUp = DressUpView->getObject<PartDesign::DressUp>();
|
| | std::vector<std::string> result = pcDressUp->Base.getSubValues();
|
| | return result;
|
| | }
|
| |
|
| |
|
| | void TaskDressUpParameters::removeItemFromListWidget(QListWidget* widget, const char* itemstr)
|
| | {
|
| | QList<QListWidgetItem*> items = widget->findItems(QString::fromLatin1(itemstr), Qt::MatchExactly);
|
| | if (!items.empty()) {
|
| | for (auto item : items) {
|
| | QListWidgetItem* it = widget->takeItem(widget->row(item));
|
| | delete it;
|
| | }
|
| | }
|
| | }
|
| |
|
| | void TaskDressUpParameters::hideOnError()
|
| | {
|
| | App::DocumentObject* dressup = DressUpView->getObject();
|
| | DressUpView->setErrorState(dressup->isError());
|
| | }
|
| |
|
| | ViewProviderDressUp* TaskDressUpParameters::getDressUpView() const
|
| | {
|
| | return DressUpView.expired() ? nullptr : DressUpView.get();
|
| | }
|
| |
|
| | Part::Feature* TaskDressUpParameters::getBase() const
|
| | {
|
| | if (ViewProviderDressUp* vp = getDressUpView()) {
|
| | auto dressUp = vp->getObject<PartDesign::DressUp>();
|
| |
|
| |
|
| |
|
| |
|
| | return dressUp->getBaseObject();
|
| | }
|
| |
|
| | return nullptr;
|
| | }
|
| |
|
| | void TaskDressUpParameters::setSelectionMode(selectionModes mode)
|
| | {
|
| | if (DressUpView.expired()) {
|
| | return;
|
| | }
|
| |
|
| | selectionMode = mode;
|
| | setButtons(mode);
|
| |
|
| | if (mode == none) {
|
| | Gui::Selection().rmvSelectionGate();
|
| |
|
| |
|
| | DressUpView->highlightReferences(false);
|
| |
|
| | if (previouslyShownViewProvider != nullptr) {
|
| |
|
| | previouslyShownViewProvider->show();
|
| | previouslyShownViewProvider = nullptr;
|
| | }
|
| | }
|
| | else {
|
| | AllowSelectionFlags allow;
|
| | allow.setFlag(AllowSelection::EDGE, allowEdges);
|
| | allow.setFlag(AllowSelection::FACE, allowFaces);
|
| | Gui::Selection().addSelectionGate(new ReferenceSelection(this->getBase(), allow));
|
| |
|
| | DressUpView->highlightReferences(true);
|
| |
|
| |
|
| |
|
| | previouslyShownViewProvider = DressUpView->getBodyViewProvider()->getShownViewProvider();
|
| | DressUpView->showPreviousFeature(true);
|
| | }
|
| |
|
| | Gui::Selection().clearSelection();
|
| | }
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| | TaskDlgDressUpParameters::TaskDlgDressUpParameters(ViewProviderDressUp* DressUpView)
|
| | : TaskDlgFeatureParameters(DressUpView)
|
| | , parameter(nullptr)
|
| | {
|
| | assert(DressUpView);
|
| | auto pcDressUp = DressUpView->getObject<PartDesign::DressUp>();
|
| | auto base = pcDressUp->Base.getValue();
|
| | std::vector<std::string> newSubList;
|
| | bool changed = false;
|
| | auto& shadowSubs = pcDressUp->Base.getShadowSubs();
|
| | for (auto& shadowSub : shadowSubs) {
|
| | auto displayName = shadowSub.oldName;
|
| |
|
| | if (boost::starts_with(shadowSub.oldName, Data::MISSING_PREFIX)) {
|
| | Part::Feature::guessNewLink(displayName, base, shadowSub.newName.c_str());
|
| | newSubList.emplace_back(displayName);
|
| | changed = true;
|
| | }
|
| | }
|
| | if (changed) {
|
| | pcDressUp->Base.setValue(base, newSubList);
|
| | }
|
| | }
|
| |
|
| | TaskDlgDressUpParameters::~TaskDlgDressUpParameters() = default;
|
| |
|
| |
|
| |
|
| | bool TaskDlgDressUpParameters::accept()
|
| | {
|
| | getViewObject<ViewProviderDressUp>()->highlightReferences(false);
|
| | std::vector<std::string> refs = parameter->getReferences();
|
| | std::stringstream str;
|
| | str << Gui::Command::getObjectCmd(getObject()) << ".Base = ("
|
| | << Gui::Command::getObjectCmd(parameter->getBase()) << ",[";
|
| | for (const auto& ref : refs) {
|
| | str << "\"" << ref << "\",";
|
| | }
|
| | str << "])";
|
| | Gui::Command::runCommand(Gui::Command::Doc, str.str().c_str());
|
| | return TaskDlgFeatureParameters::accept();
|
| | }
|
| |
|
| | bool TaskDlgDressUpParameters::reject()
|
| | {
|
| | getViewObject<ViewProviderDressUp>()->highlightReferences(false);
|
| | return TaskDlgFeatureParameters::reject();
|
| | }
|
| |
|
| | #include "moc_TaskDressUpParameters.cpp"
|
| |
|