From 4590305921fd8d3a2c4d294c222e1df0240d64f5 Mon Sep 17 00:00:00 2001 From: Alexander Golubev Date: Mon, 20 Jul 2015 22:59:37 +0300 Subject: [PATCH] PartDesign/Gui: enhance the TaskFeaturePick with new cotegory of sketches: notInBody Also add option tp show already used sketches and fix some spacing. --- src/Mod/PartDesign/Gui/Command.cpp | 53 +++++++++----- src/Mod/PartDesign/Gui/TaskFeaturePick.cpp | 81 ++++++++++++++-------- src/Mod/PartDesign/Gui/TaskFeaturePick.h | 1 + src/Mod/PartDesign/Gui/TaskFeaturePick.ui | 43 +++++++++++- 4 files changed, 127 insertions(+), 51 deletions(-) diff --git a/src/Mod/PartDesign/Gui/Command.cpp b/src/Mod/PartDesign/Gui/Command.cpp index 417bf80bc..586a155b9 100644 --- a/src/Mod/PartDesign/Gui/Command.cpp +++ b/src/Mod/PartDesign/Gui/Command.cpp @@ -930,28 +930,38 @@ void finishFeature(const Gui::Command* cmd, const std::string& FeatName, const b const unsigned validateSketches(std::vector& sketches, std::vector& status, std::vector::iterator& firstValidSketch) -{ - PartDesign::Body* pcActiveBody = PartDesignGui::getBody(false); - App::Part* pcActivePart = PartDesignGui::getPartFor(pcActiveBody, false); - +{ + PartDesign::Body* pcActiveBody = PartDesignGui::getBody(false); + App::Part* pcActivePart = PartDesignGui::getPartFor(pcActiveBody, false); + // TODO: If the user previously opted to allow multiple use of sketches or use of sketches from other bodies, // then count these as valid sketches! unsigned validSketches = 0; firstValidSketch = sketches.end(); for (std::vector::iterator s = sketches.begin(); s != sketches.end(); s++) { - - // Check whether this plane belongs to the active body - if (pcActiveBody && !pcActiveBody->hasFeature(*s)) { - if(pcActivePart && pcActivePart->hasObject(*s, true)) - status.push_back(PartDesignGui::TaskFeaturePick::otherBody); - else + + if (!pcActiveBody) { + // We work in the old style outside any body + if (PartDesign::Body::findBodyOf (*s)) { status.push_back(PartDesignGui::TaskFeaturePick::otherPart); - + ++validSketches; + continue; + } + } else if (!pcActiveBody->hasFeature(*s)) { + // Check whether this plane belongs to the active body + if(pcActivePart && pcActivePart->hasObject(*s, true)) { + status.push_back(PartDesignGui::TaskFeaturePick::otherBody); + } else if (PartDesign::Body::findBodyOf(*s)) { + status.push_back(PartDesignGui::TaskFeaturePick::otherPart); + } else { + status.push_back(PartDesignGui::TaskFeaturePick::notInBody); + } + ++validSketches; continue; } - + //Base::Console().Error("Checking sketch %s\n", (*s)->getNameInDocument()); // Check whether this sketch is already being used by another feature // Body features don't count... @@ -970,7 +980,7 @@ void finishFeature(const Gui::Command* cmd, const std::string& FeatName, const b status.push_back(PartDesignGui::TaskFeaturePick::isUsed); continue; } - + if (pcActiveBody && pcActiveBody->isAfterTip(*s)){ status.push_back(PartDesignGui::TaskFeaturePick::afterTip); continue; @@ -1053,17 +1063,22 @@ void prepareSketchBased(Gui::Command* cmd, const std::string& which, func(sketch, FeatName); }; - - //if there is a sketch selected which is from annother body or part we need to bring up the + + //if there is a sketch selected which is from annother body or part we need to bring up the //pick task dialog to decide how those are handled - bool ext = std::find(status.begin(), status.end(), PartDesignGui::TaskFeaturePick::otherBody) != status.end(); - ext |= std::find(status.begin(), status.end(), PartDesignGui::TaskFeaturePick::otherPart) != status.end(); + bool ext = std::find_if( status.begin(), status.end(), + [] (const PartDesignGui::TaskFeaturePick::featureStatus& s) { + return s == PartDesignGui::TaskFeaturePick::otherBody || + s == PartDesignGui::TaskFeaturePick::otherPart || + s == PartDesignGui::TaskFeaturePick::notInBody; + } + ) != status.end(); // If there is more than one selection/possibility, show dialog and let user pick sketch if ((bNoSketchWasSelected && validSketches > 1) || (!bNoSketchWasSelected && sketches.size() > 1) || ext ) { - + Gui::TaskView::TaskDialog *dlg = Gui::Control().activeDialog(); PartDesignGui::TaskDlgFeaturePick *pickDlg = qobject_cast(dlg); if (dlg && !pickDlg) { @@ -1086,7 +1101,7 @@ void prepareSketchBased(Gui::Command* cmd, const std::string& which, pickDlg = new PartDesignGui::TaskDlgFeaturePick(sketches, status, accepter, worker); if(ext) pickDlg->showExternal(true); - + Gui::Control().showDialog(pickDlg); } else { diff --git a/src/Mod/PartDesign/Gui/TaskFeaturePick.cpp b/src/Mod/PartDesign/Gui/TaskFeaturePick.cpp index 8b15e58f2..f0988b338 100644 --- a/src/Mod/PartDesign/Gui/TaskFeaturePick.cpp +++ b/src/Mod/PartDesign/Gui/TaskFeaturePick.cpp @@ -42,6 +42,7 @@ #include "TaskFeaturePick.h" #include "Workbench.h" #include +#include using namespace PartDesignGui; @@ -54,6 +55,7 @@ const QString TaskFeaturePick::getFeatureStatusString(const featureStatus st) case isUsed: return tr("Sketch already used by other feature"); case otherBody: return tr("Belongs to another body"); case otherPart: return tr("Belongs to another part"); + case notInBody: return tr("Doesn't belongs to any body"); case basePlane: return tr("Base plane"); case afterTip: return tr("Feature is located after the tip feature"); } @@ -67,10 +69,11 @@ TaskFeaturePick::TaskFeaturePick(std::vector& objects, : TaskBox(Gui::BitmapFactory().pixmap("edit-select-box"), QString::fromAscii("Select feature"), true, parent), ui(new Ui_TaskFeaturePick) { - + proxy = new QWidget(this); ui->setupUi(proxy); + connect(ui->checkUsed, SIGNAL(toggled(bool)), this, SLOT(onUpdate(bool))); connect(ui->checkOtherBody, SIGNAL(toggled(bool)), this, SLOT(onUpdate(bool))); connect(ui->bodyRadioIndependent, SIGNAL(toggled(bool)), this, SLOT(onUpdate(bool))); connect(ui->bodyRadioXRef, SIGNAL(toggled(bool)), this, SLOT(onUpdate(bool))); @@ -78,7 +81,10 @@ TaskFeaturePick::TaskFeaturePick(std::vector& objects, connect(ui->partRadioIndependent, SIGNAL(toggled(bool)), this, SLOT(onUpdate(bool))); connect(ui->partRadioDependent, SIGNAL(toggled(bool)), this, SLOT(onUpdate(bool))); connect(ui->partRadioXRef, SIGNAL(toggled(bool)), this, SLOT(onUpdate(bool))); - + connect(ui->checkNoBody, SIGNAL(toggled(bool)), this, SLOT(onUpdate(bool))); + connect(ui->nobodyRadioIndependent, SIGNAL(toggled(bool)), this, SLOT(onUpdate(bool))); + connect(ui->nobodyRadioXRef, SIGNAL(toggled(bool)), this, SLOT(onUpdate(bool))); + auto guidoc = Gui::Application::Instance->activeDocument(); auto origin_obj = App::GetApplication().getActiveDocument()->getObjectsOfType(); @@ -88,20 +94,20 @@ TaskFeaturePick::TaskFeaturePick(std::vector& objects, QListWidgetItem* item = new QListWidgetItem(QString::fromAscii((*o)->getNameInDocument()) + QString::fromAscii(" (") + getFeatureStatusString(*st) + QString::fromAscii(")")); ui->listWidget->addItem(item); - + //check if we need to set any origin in temporary visibility mode for(App::Origin* obj : origin_obj) { if(obj->hasObject(*o) && (*st != invalidShape)) { Gui::ViewProviderOrigin* vpo = static_cast(guidoc->getViewProvider(obj)); if(!vpo->isTemporaryVisibilityMode()) vpo->setTemporaryVisibilityMode(true, guidoc); - + vpo->setTemporaryVisibility(*o, true); origins.push_back(vpo); break; } } - + st++; } @@ -120,19 +126,21 @@ TaskFeaturePick::~TaskFeaturePick() void TaskFeaturePick::updateList() { int index = 0; - + //get all origins in temporary mode - - + + for (std::vector::const_iterator st = statuses.begin(); st != statuses.end(); st++) { QListWidgetItem* item = ui->listWidget->item(index); switch (*st) { case validFeature: item->setHidden(false); break; case invalidShape: item->setHidden(true); break; + case isUsed: item->setHidden(!ui->checkUsed->isChecked()); break; case noWire: item->setHidden(true); break; - case otherBody: item->setHidden(ui->checkOtherBody->isChecked() ? false : true); break; - case otherPart: item->setHidden(ui->checkOtherPart->isChecked() ? false : true); break; + case otherBody: item->setHidden(!ui->checkOtherBody->isChecked()); break; + case otherPart: item->setHidden(!ui->checkOtherPart->isChecked()); break; + case notInBody: item->setHidden(!ui->checkNoBody->isChecked()); break; case basePlane: item->setHidden(false); break; case afterTip: item->setHidden(true); break; } @@ -170,52 +178,64 @@ std::vector TaskFeaturePick::getFeatures() { } std::vector TaskFeaturePick::buildFeatures() { - - int index = 0; + int index = 0; std::vector result; auto activeBody = PartDesignGui::getBody(false); auto activePart = PartDesignGui::getPartFor(activeBody, false); - + for (std::vector::const_iterator st = statuses.begin(); st != statuses.end(); st++) { QListWidgetItem* item = ui->listWidget->item(index); if(item->isSelected() && !item->isHidden()) { - + QString t = item->text(); t = t.left(t.indexOf(QString::fromAscii("(")) - 1); auto obj = App::GetApplication().getActiveDocument()->getObject(t.toAscii().data()); - + //build the dependend copy if wanted by the user if(*st == otherBody) { - - if(ui->bodyRadioIndependent->isChecked()) { + + if(ui->bodyRadioIndependent->isChecked()) { auto copy = makeCopy(obj, true); activeBody->addFeature(copy); result.push_back(copy); - } - else + } else { result.push_back(obj); + } } else if(*st == otherPart) { - - if(!ui->partRadioXRef->isChecked()) { + + if(!ui->partRadioXRef->isChecked()) { auto copy = makeCopy(obj, ui->partRadioIndependent->isChecked()); - + auto oBody = PartDesignGui::getBodyFor(obj, false); if(oBody) activeBody->addFeature(copy); - else + else activePart->addObject(copy); - + result.push_back(copy); } - else - result.push_back(obj); + else + result.push_back(obj); + } else if(*st == notInBody) { + if(ui->bodyRadioIndependent->isChecked()) { + auto copy = makeCopy(obj, true); + activeBody->addFeature(copy); + // doesn't supposed to get here anything but sketch but to be on the safe side better to check + if (copy->getTypeId().isDerivedFrom(Sketcher::SketchObject::getClassTypeId())) { + Sketcher::SketchObject *sketch = static_cast(copy); + Workbench::fixSketchSupport(sketch); + } + result.push_back(copy); + } + else + result.push_back(obj); } - else + else result.push_back(obj); - + break; } @@ -227,7 +247,7 @@ std::vector TaskFeaturePick::buildFeatures() { App::DocumentObject* TaskFeaturePick::makeCopy(App::DocumentObject* obj, bool independent) { - //we do know that the created instance is a document object, as obj is one. But we do not know which + //we do know that the created instance is a document object, as obj is one. But we do not know which //exact type auto name = std::string("Copy") + std::string(obj->getNameInDocument()); auto copy = App::GetApplication().getActiveDocument()->addObject(obj->getTypeId().getName(), name.c_str()); @@ -288,13 +308,14 @@ void TaskFeaturePick::onSelectionChanged(const Gui::SelectionChanges& msg) ui->listWidget->setItemSelected(item, true); } } - } + } } void TaskFeaturePick::showExternal(bool val) { ui->checkOtherBody->setChecked(val); ui->checkOtherPart->setChecked(val); + ui->checkNoBody->setChecked(val); updateList(); } diff --git a/src/Mod/PartDesign/Gui/TaskFeaturePick.h b/src/Mod/PartDesign/Gui/TaskFeaturePick.h index 6523a082f..3f1346d1d 100644 --- a/src/Mod/PartDesign/Gui/TaskFeaturePick.h +++ b/src/Mod/PartDesign/Gui/TaskFeaturePick.h @@ -47,6 +47,7 @@ public: isUsed, otherBody, otherPart, + notInBody, basePlane, afterTip }; diff --git a/src/Mod/PartDesign/Gui/TaskFeaturePick.ui b/src/Mod/PartDesign/Gui/TaskFeaturePick.ui index 9af17c6a2..bd856c56d 100644 --- a/src/Mod/PartDesign/Gui/TaskFeaturePick.ui +++ b/src/Mod/PartDesign/Gui/TaskFeaturePick.ui @@ -7,16 +7,23 @@ 0 0 388 - 479 + 493 Form - + + + + + Allow used features + + + @@ -91,6 +98,38 @@ + + + + Allow features not belong to any body + + + true + + + false + + + + + + Make independent copy (recommended) + + + true + + + + + + + Create cross-reference + + + + + +