PartDesign/Gui: enhance the TaskFeaturePick with new cotegory of sketches: notInBody

Also add option tp show already used sketches and fix some spacing.
This commit is contained in:
Alexander Golubev 2015-07-20 22:59:37 +03:00 committed by Stefan Tröger
parent ffc6cc2f23
commit 4590305921
4 changed files with 127 additions and 51 deletions

View File

@ -930,28 +930,38 @@ void finishFeature(const Gui::Command* cmd, const std::string& FeatName, const b
const unsigned validateSketches(std::vector<App::DocumentObject*>& sketches, const unsigned validateSketches(std::vector<App::DocumentObject*>& sketches,
std::vector<PartDesignGui::TaskFeaturePick::featureStatus>& status, std::vector<PartDesignGui::TaskFeaturePick::featureStatus>& status,
std::vector<App::DocumentObject*>::iterator& firstValidSketch) std::vector<App::DocumentObject*>::iterator& firstValidSketch)
{ {
PartDesign::Body* pcActiveBody = PartDesignGui::getBody(false); PartDesign::Body* pcActiveBody = PartDesignGui::getBody(false);
App::Part* pcActivePart = PartDesignGui::getPartFor(pcActiveBody, 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, // 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! // then count these as valid sketches!
unsigned validSketches = 0; unsigned validSketches = 0;
firstValidSketch = sketches.end(); firstValidSketch = sketches.end();
for (std::vector<App::DocumentObject*>::iterator s = sketches.begin(); s != sketches.end(); s++) { for (std::vector<App::DocumentObject*>::iterator s = sketches.begin(); s != sketches.end(); s++) {
// Check whether this plane belongs to the active body if (!pcActiveBody) {
if (pcActiveBody && !pcActiveBody->hasFeature(*s)) { // We work in the old style outside any body
if(pcActivePart && pcActivePart->hasObject(*s, true)) if (PartDesign::Body::findBodyOf (*s)) {
status.push_back(PartDesignGui::TaskFeaturePick::otherBody);
else
status.push_back(PartDesignGui::TaskFeaturePick::otherPart); 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; ++validSketches;
continue; continue;
} }
//Base::Console().Error("Checking sketch %s\n", (*s)->getNameInDocument()); //Base::Console().Error("Checking sketch %s\n", (*s)->getNameInDocument());
// Check whether this sketch is already being used by another feature // Check whether this sketch is already being used by another feature
// Body features don't count... // 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); status.push_back(PartDesignGui::TaskFeaturePick::isUsed);
continue; continue;
} }
if (pcActiveBody && pcActiveBody->isAfterTip(*s)){ if (pcActiveBody && pcActiveBody->isAfterTip(*s)){
status.push_back(PartDesignGui::TaskFeaturePick::afterTip); status.push_back(PartDesignGui::TaskFeaturePick::afterTip);
continue; continue;
@ -1053,17 +1063,22 @@ void prepareSketchBased(Gui::Command* cmd, const std::string& which,
func(sketch, FeatName); 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 //pick task dialog to decide how those are handled
bool ext = std::find(status.begin(), status.end(), PartDesignGui::TaskFeaturePick::otherBody) != status.end(); bool ext = std::find_if( status.begin(), status.end(),
ext |= std::find(status.begin(), status.end(), PartDesignGui::TaskFeaturePick::otherPart) != 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 there is more than one selection/possibility, show dialog and let user pick sketch
if ((bNoSketchWasSelected && validSketches > 1) || if ((bNoSketchWasSelected && validSketches > 1) ||
(!bNoSketchWasSelected && sketches.size() > 1) || (!bNoSketchWasSelected && sketches.size() > 1) ||
ext ) { ext ) {
Gui::TaskView::TaskDialog *dlg = Gui::Control().activeDialog(); Gui::TaskView::TaskDialog *dlg = Gui::Control().activeDialog();
PartDesignGui::TaskDlgFeaturePick *pickDlg = qobject_cast<PartDesignGui::TaskDlgFeaturePick *>(dlg); PartDesignGui::TaskDlgFeaturePick *pickDlg = qobject_cast<PartDesignGui::TaskDlgFeaturePick *>(dlg);
if (dlg && !pickDlg) { if (dlg && !pickDlg) {
@ -1086,7 +1101,7 @@ void prepareSketchBased(Gui::Command* cmd, const std::string& which,
pickDlg = new PartDesignGui::TaskDlgFeaturePick(sketches, status, accepter, worker); pickDlg = new PartDesignGui::TaskDlgFeaturePick(sketches, status, accepter, worker);
if(ext) if(ext)
pickDlg->showExternal(true); pickDlg->showExternal(true);
Gui::Control().showDialog(pickDlg); Gui::Control().showDialog(pickDlg);
} }
else { else {

View File

@ -42,6 +42,7 @@
#include "TaskFeaturePick.h" #include "TaskFeaturePick.h"
#include "Workbench.h" #include "Workbench.h"
#include <Mod/PartDesign/App/Body.h> #include <Mod/PartDesign/App/Body.h>
#include <Mod/Sketcher/App/SketchObject.h>
using namespace PartDesignGui; 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 isUsed: return tr("Sketch already used by other feature");
case otherBody: return tr("Belongs to another body"); case otherBody: return tr("Belongs to another body");
case otherPart: return tr("Belongs to another part"); 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 basePlane: return tr("Base plane");
case afterTip: return tr("Feature is located after the tip feature"); case afterTip: return tr("Feature is located after the tip feature");
} }
@ -67,10 +69,11 @@ TaskFeaturePick::TaskFeaturePick(std::vector<App::DocumentObject*>& objects,
: TaskBox(Gui::BitmapFactory().pixmap("edit-select-box"), : TaskBox(Gui::BitmapFactory().pixmap("edit-select-box"),
QString::fromAscii("Select feature"), true, parent), ui(new Ui_TaskFeaturePick) QString::fromAscii("Select feature"), true, parent), ui(new Ui_TaskFeaturePick)
{ {
proxy = new QWidget(this); proxy = new QWidget(this);
ui->setupUi(proxy); 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->checkOtherBody, SIGNAL(toggled(bool)), this, SLOT(onUpdate(bool)));
connect(ui->bodyRadioIndependent, 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))); connect(ui->bodyRadioXRef, SIGNAL(toggled(bool)), this, SLOT(onUpdate(bool)));
@ -78,7 +81,10 @@ TaskFeaturePick::TaskFeaturePick(std::vector<App::DocumentObject*>& objects,
connect(ui->partRadioIndependent, SIGNAL(toggled(bool)), this, SLOT(onUpdate(bool))); connect(ui->partRadioIndependent, SIGNAL(toggled(bool)), this, SLOT(onUpdate(bool)));
connect(ui->partRadioDependent, 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->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 guidoc = Gui::Application::Instance->activeDocument();
auto origin_obj = App::GetApplication().getActiveDocument()->getObjectsOfType<App::Origin>(); auto origin_obj = App::GetApplication().getActiveDocument()->getObjectsOfType<App::Origin>();
@ -88,20 +94,20 @@ TaskFeaturePick::TaskFeaturePick(std::vector<App::DocumentObject*>& objects,
QListWidgetItem* item = new QListWidgetItem(QString::fromAscii((*o)->getNameInDocument()) + QListWidgetItem* item = new QListWidgetItem(QString::fromAscii((*o)->getNameInDocument()) +
QString::fromAscii(" (") + getFeatureStatusString(*st) + QString::fromAscii(")")); QString::fromAscii(" (") + getFeatureStatusString(*st) + QString::fromAscii(")"));
ui->listWidget->addItem(item); ui->listWidget->addItem(item);
//check if we need to set any origin in temporary visibility mode //check if we need to set any origin in temporary visibility mode
for(App::Origin* obj : origin_obj) { for(App::Origin* obj : origin_obj) {
if(obj->hasObject(*o) && (*st != invalidShape)) { if(obj->hasObject(*o) && (*st != invalidShape)) {
Gui::ViewProviderOrigin* vpo = static_cast<Gui::ViewProviderOrigin*>(guidoc->getViewProvider(obj)); Gui::ViewProviderOrigin* vpo = static_cast<Gui::ViewProviderOrigin*>(guidoc->getViewProvider(obj));
if(!vpo->isTemporaryVisibilityMode()) if(!vpo->isTemporaryVisibilityMode())
vpo->setTemporaryVisibilityMode(true, guidoc); vpo->setTemporaryVisibilityMode(true, guidoc);
vpo->setTemporaryVisibility(*o, true); vpo->setTemporaryVisibility(*o, true);
origins.push_back(vpo); origins.push_back(vpo);
break; break;
} }
} }
st++; st++;
} }
@ -120,19 +126,21 @@ TaskFeaturePick::~TaskFeaturePick()
void TaskFeaturePick::updateList() void TaskFeaturePick::updateList()
{ {
int index = 0; int index = 0;
//get all origins in temporary mode //get all origins in temporary mode
for (std::vector<featureStatus>::const_iterator st = statuses.begin(); st != statuses.end(); st++) { for (std::vector<featureStatus>::const_iterator st = statuses.begin(); st != statuses.end(); st++) {
QListWidgetItem* item = ui->listWidget->item(index); QListWidgetItem* item = ui->listWidget->item(index);
switch (*st) { switch (*st) {
case validFeature: item->setHidden(false); break; case validFeature: item->setHidden(false); break;
case invalidShape: item->setHidden(true); break; case invalidShape: item->setHidden(true); break;
case isUsed: item->setHidden(!ui->checkUsed->isChecked()); break;
case noWire: item->setHidden(true); break; case noWire: item->setHidden(true); break;
case otherBody: item->setHidden(ui->checkOtherBody->isChecked() ? false : true); break; case otherBody: item->setHidden(!ui->checkOtherBody->isChecked()); break;
case otherPart: item->setHidden(ui->checkOtherPart->isChecked() ? false : true); break; case otherPart: item->setHidden(!ui->checkOtherPart->isChecked()); break;
case notInBody: item->setHidden(!ui->checkNoBody->isChecked()); break;
case basePlane: item->setHidden(false); break; case basePlane: item->setHidden(false); break;
case afterTip: item->setHidden(true); break; case afterTip: item->setHidden(true); break;
} }
@ -170,52 +178,64 @@ std::vector<App::DocumentObject*> TaskFeaturePick::getFeatures() {
} }
std::vector<App::DocumentObject*> TaskFeaturePick::buildFeatures() { std::vector<App::DocumentObject*> TaskFeaturePick::buildFeatures() {
int index = 0; int index = 0;
std::vector<App::DocumentObject*> result; std::vector<App::DocumentObject*> result;
auto activeBody = PartDesignGui::getBody(false); auto activeBody = PartDesignGui::getBody(false);
auto activePart = PartDesignGui::getPartFor(activeBody, false); auto activePart = PartDesignGui::getPartFor(activeBody, false);
for (std::vector<featureStatus>::const_iterator st = statuses.begin(); st != statuses.end(); st++) { for (std::vector<featureStatus>::const_iterator st = statuses.begin(); st != statuses.end(); st++) {
QListWidgetItem* item = ui->listWidget->item(index); QListWidgetItem* item = ui->listWidget->item(index);
if(item->isSelected() && !item->isHidden()) { if(item->isSelected() && !item->isHidden()) {
QString t = item->text(); QString t = item->text();
t = t.left(t.indexOf(QString::fromAscii("(")) - 1); t = t.left(t.indexOf(QString::fromAscii("(")) - 1);
auto obj = App::GetApplication().getActiveDocument()->getObject(t.toAscii().data()); auto obj = App::GetApplication().getActiveDocument()->getObject(t.toAscii().data());
//build the dependend copy if wanted by the user //build the dependend copy if wanted by the user
if(*st == otherBody) { if(*st == otherBody) {
if(ui->bodyRadioIndependent->isChecked()) { if(ui->bodyRadioIndependent->isChecked()) {
auto copy = makeCopy(obj, true); auto copy = makeCopy(obj, true);
activeBody->addFeature(copy); activeBody->addFeature(copy);
result.push_back(copy); result.push_back(copy);
} } else {
else
result.push_back(obj); result.push_back(obj);
}
} }
else if(*st == otherPart) { else if(*st == otherPart) {
if(!ui->partRadioXRef->isChecked()) { if(!ui->partRadioXRef->isChecked()) {
auto copy = makeCopy(obj, ui->partRadioIndependent->isChecked()); auto copy = makeCopy(obj, ui->partRadioIndependent->isChecked());
auto oBody = PartDesignGui::getBodyFor(obj, false); auto oBody = PartDesignGui::getBodyFor(obj, false);
if(oBody) if(oBody)
activeBody->addFeature(copy); activeBody->addFeature(copy);
else else
activePart->addObject(copy); activePart->addObject(copy);
result.push_back(copy); result.push_back(copy);
} }
else else
result.push_back(obj); 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<Sketcher::SketchObject*>(copy);
Workbench::fixSketchSupport(sketch);
}
result.push_back(copy);
}
else
result.push_back(obj);
} }
else else
result.push_back(obj); result.push_back(obj);
break; break;
} }
@ -227,7 +247,7 @@ std::vector<App::DocumentObject*> TaskFeaturePick::buildFeatures() {
App::DocumentObject* TaskFeaturePick::makeCopy(App::DocumentObject* obj, bool independent) { 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 //exact type
auto name = std::string("Copy") + std::string(obj->getNameInDocument()); auto name = std::string("Copy") + std::string(obj->getNameInDocument());
auto copy = App::GetApplication().getActiveDocument()->addObject(obj->getTypeId().getName(), name.c_str()); 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); ui->listWidget->setItemSelected(item, true);
} }
} }
} }
} }
void TaskFeaturePick::showExternal(bool val) { void TaskFeaturePick::showExternal(bool val) {
ui->checkOtherBody->setChecked(val); ui->checkOtherBody->setChecked(val);
ui->checkOtherPart->setChecked(val); ui->checkOtherPart->setChecked(val);
ui->checkNoBody->setChecked(val);
updateList(); updateList();
} }

View File

@ -47,6 +47,7 @@ public:
isUsed, isUsed,
otherBody, otherBody,
otherPart, otherPart,
notInBody,
basePlane, basePlane,
afterTip afterTip
}; };

View File

@ -7,16 +7,23 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>388</width> <width>388</width>
<height>479</height> <height>493</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
<string>Form</string> <string>Form</string>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout_3"> <layout class="QVBoxLayout" name="verticalLayout_4">
<item> <item>
<widget class="QListWidget" name="listWidget"/> <widget class="QListWidget" name="listWidget"/>
</item> </item>
<item>
<widget class="QCheckBox" name="checkUsed">
<property name="text">
<string>Allow used features</string>
</property>
</widget>
</item>
<item> <item>
<widget class="QGroupBox" name="checkOtherBody"> <widget class="QGroupBox" name="checkOtherBody">
<property name="title"> <property name="title">
@ -91,6 +98,38 @@
</layout> </layout>
</widget> </widget>
</item> </item>
<item>
<widget class="QGroupBox" name="checkNoBody">
<property name="title">
<string>Allow features not belong to any body</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>false</bool>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QRadioButton" name="nobodyRadioIndependent">
<property name="text">
<string>Make independent copy (recommended)</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="nobodyRadioXRef">
<property name="text">
<string>Create cross-reference</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout> </layout>
</widget> </widget>
<resources/> <resources/>