PD: [skip ci] fixes #0004205: Bad behavior when entering manually PD/AdditivePipe path

This commit is contained in:
wmayer
2021-02-15 00:06:29 +01:00
parent 3017fd5902
commit abed4bd421
2 changed files with 116 additions and 93 deletions

View File

@@ -436,6 +436,113 @@ void TaskPipeParameters::exitSelectionMode() {
Gui::Selection().clearSelection();
}
bool TaskPipeParameters::accept()
{
//see what to do with external references
//check the prerequisites for the selected objects
//the user has to decide which option we should take if external references are used
PartDesign::Pipe* pcPipe = static_cast<PartDesign::Pipe*>(getPipeView()->getObject());
auto pcActiveBody = PartDesignGui::getBodyFor(pcPipe, false);
if (!pcActiveBody) {
QMessageBox::warning(this, tr("Input error"), tr("No active body"));
return false;
}
//auto pcActivePart = PartDesignGui::getPartFor(pcActiveBody, false);
std::vector<App::DocumentObject*> copies;
bool extReference = false;
App::DocumentObject* spine = pcPipe->Spine.getValue();
App::DocumentObject* auxSpine = pcPipe->AuxillerySpine.getValue();
// If a spine isn't set but user entered a label then search for the appropriate document object
QString label = ui->spineBaseEdit->text();
if (!spine && !label.isEmpty()) {
QByteArray ba = label.toUtf8();
std::vector<App::DocumentObject*> objs = pcPipe->getDocument()->findObjects(App::DocumentObject::getClassTypeId(), nullptr, ba.constData());
if (!objs.empty()) {
pcPipe->Spine.setValue(objs.front());
spine = objs.front();
}
}
if (spine && !pcActiveBody->hasObject(spine) && !pcActiveBody->getOrigin()->hasObject(spine)) {
extReference = true;
}
else if (auxSpine && !pcActiveBody->hasObject(auxSpine) && !pcActiveBody->getOrigin()->hasObject(auxSpine)) {
extReference = true;
}
else {
for(App::DocumentObject* obj : pcPipe->Sections.getValues()) {
if (!pcActiveBody->hasObject(obj) && !pcActiveBody->getOrigin()->hasObject(obj)) {
extReference = true;
break;
}
}
}
if (extReference) {
QDialog dia(Gui::getMainWindow());
Ui_DlgReference dlg;
dlg.setupUi(&dia);
dia.setModal(true);
int result = dia.exec();
if (result == QDialog::DialogCode::Rejected)
return false;
if (!dlg.radioXRef->isChecked()) {
if (!pcActiveBody->hasObject(spine) && !pcActiveBody->getOrigin()->hasObject(spine)) {
pcPipe->Spine.setValue(PartDesignGui::TaskFeaturePick::makeCopy(spine, "",
dlg.radioIndependent->isChecked()),
pcPipe->Spine.getSubValues());
copies.push_back(pcPipe->Spine.getValue());
}
else if (!pcActiveBody->hasObject(auxSpine) && !pcActiveBody->getOrigin()->hasObject(auxSpine)){
pcPipe->AuxillerySpine.setValue(PartDesignGui::TaskFeaturePick::makeCopy(auxSpine, "",
dlg.radioIndependent->isChecked()),
pcPipe->AuxillerySpine.getSubValues());
copies.push_back(pcPipe->AuxillerySpine.getValue());
}
std::vector<App::DocumentObject*> objs;
int index = 0;
for(App::DocumentObject* obj : pcPipe->Sections.getValues()) {
if(!pcActiveBody->hasObject(obj) && !pcActiveBody->getOrigin()->hasObject(obj)) {
objs.push_back(PartDesignGui::TaskFeaturePick::makeCopy(obj, "", dlg.radioIndependent->isChecked()));
copies.push_back(objs.back());
}
else {
objs.push_back(obj);
}
index++;
}
pcPipe->Sections.setValues(objs);
}
}
try {
Gui::cmdAppDocument(pcPipe, "recompute()");
if (!vp->getObject()->isValid())
throw Base::RuntimeError(vp->getObject()->getStatusString());
Gui::cmdGuiDocument(pcPipe, "resetEdit()");
Gui::Command::commitCommand();
//we need to add the copied features to the body after the command action, as otherwise FreeCAD crashes unexplainably
for (auto obj : copies) {
pcActiveBody->addObject(obj);
}
}
catch (const Base::Exception& e) {
QMessageBox::warning(this, tr("Input error"), QString::fromUtf8(e.what()));
return false;
}
return true;
}
//**************************************************************************
//**************************************************************************
@@ -1014,89 +1121,7 @@ TaskDlgPipeParameters::~TaskDlgPipeParameters()
bool TaskDlgPipeParameters::accept()
{
//see what to do with external references
//check the prerequisites for the selected objects
//the user has to decide which option we should take if external references are used
PartDesign::Pipe* pcPipe = static_cast<PartDesign::Pipe*>(getPipeView()->getObject());
auto pcActiveBody = PartDesignGui::getBodyFor(pcPipe, false);
//auto pcActivePart = PartDesignGui::getPartFor(pcActiveBody, false);
std::vector<App::DocumentObject*> copies;
bool extReference = false;
if(!pcActiveBody->hasObject(pcPipe->Spine.getValue()) && !pcActiveBody->getOrigin()->hasObject(pcPipe->Spine.getValue()))
extReference = true;
else if(pcPipe->AuxillerySpine.getValue() && !pcActiveBody->hasObject(pcPipe->AuxillerySpine.getValue()) &&
!pcActiveBody->getOrigin()->hasObject(pcPipe->AuxillerySpine.getValue()))
extReference = true;
else {
for(App::DocumentObject* obj : pcPipe->Sections.getValues()) {
if(!pcActiveBody->hasObject(obj) && !pcActiveBody->getOrigin()->hasObject(obj))
extReference = true;
}
}
if (extReference) {
QDialog dia(Gui::getMainWindow());
Ui_DlgReference dlg;
dlg.setupUi(&dia);
dia.setModal(true);
int result = dia.exec();
if (result == QDialog::DialogCode::Rejected)
return false;
if(!dlg.radioXRef->isChecked()) {
if(!pcActiveBody->hasObject(pcPipe->Spine.getValue()) && !pcActiveBody->getOrigin()->hasObject(pcPipe->Spine.getValue())) {
pcPipe->Spine.setValue(PartDesignGui::TaskFeaturePick::makeCopy(pcPipe->Spine.getValue(), "", dlg.radioIndependent->isChecked()),
pcPipe->Spine.getSubValues());
copies.push_back(pcPipe->Spine.getValue());
}
else if(!pcActiveBody->hasObject(pcPipe->AuxillerySpine.getValue()) && !pcActiveBody->getOrigin()->hasObject(pcPipe->AuxillerySpine.getValue())){
pcPipe->AuxillerySpine.setValue(PartDesignGui::TaskFeaturePick::makeCopy(pcPipe->AuxillerySpine.getValue(), "", dlg.radioIndependent->isChecked()),
pcPipe->AuxillerySpine.getSubValues());
copies.push_back(pcPipe->AuxillerySpine.getValue());
}
std::vector<App::DocumentObject*> objs;
int index = 0;
for(App::DocumentObject* obj : pcPipe->Sections.getValues()) {
if(!pcActiveBody->hasObject(obj) && !pcActiveBody->getOrigin()->hasObject(obj)) {
objs.push_back(PartDesignGui::TaskFeaturePick::makeCopy(obj, "", dlg.radioIndependent->isChecked()));
copies.push_back(objs.back());
}
else
objs.push_back(obj);
index++;
}
pcPipe->Sections.setValues(objs);
}
}
try {
Gui::cmdAppDocument(pcPipe, "recompute()");
if (!vp->getObject()->isValid())
throw Base::RuntimeError(vp->getObject()->getStatusString());
Gui::cmdGuiDocument(pcPipe, "resetEdit()");
Gui::Command::commitCommand();
//we need to add the copied features to the body after the command action, as otherwise FreeCAD crashes unexplainably
for(auto obj : copies) {
//Dead code: pcActiveBody was previously used without checking for null, so it won't be null here either.
//if(pcActiveBody)
pcActiveBody->addObject(obj);
//else if (pcActivePart)
// pcActivePart->addObject(obj);
}
}
catch (const Base::Exception& e) {
QMessageBox::warning(parameter, tr("Input error"), QString::fromUtf8(e.what()));
return false;
}
return true;
return parameter->accept();
}

View File

@@ -32,10 +32,6 @@
#include "ViewProviderPipe.h"
#include "TaskDressUpParameters.h"
class Ui_TaskPipeParameters;
class Ui_TaskPipeOrientation;
class Ui_TaskPipeScaling;
namespace App {
class Property;
@@ -47,6 +43,9 @@ class ViewProvider;
namespace PartDesignGui {
class Ui_TaskPipeParameters;
class Ui_TaskPipeOrientation;
class Ui_TaskPipeScaling;
class TaskPipeParameters : public TaskSketchBasedParameters
@@ -57,7 +56,8 @@ public:
TaskPipeParameters(ViewProviderPipe *PipeView,bool newObj=false,QWidget *parent = 0);
~TaskPipeParameters();
bool accept();
private Q_SLOTS:
void onTangentChanged(bool checked);
void onTransitionChanged(int);
@@ -80,6 +80,9 @@ private:
void clearButtons();
void exitSelectionMode();
ViewProviderPipe* getPipeView() const
{ return static_cast<ViewProviderPipe*>(vp); }
bool spineShow = false;
private:
@@ -135,7 +138,6 @@ public:
TaskPipeScaling(ViewProviderPipe *PipeView,bool newObj=false,QWidget *parent = 0);
virtual ~TaskPipeScaling();
private Q_SLOTS:
void onScalingChanged(int);
void onButtonRefAdd(bool checked);
@@ -170,10 +172,6 @@ public:
TaskDlgPipeParameters(ViewProviderPipe *PipeView,bool newObj=false);
~TaskDlgPipeParameters();
ViewProviderPipe* getPipeView() const
{ return static_cast<ViewProviderPipe*>(vp); }
public:
/// is called by the framework if the dialog is accepted (Ok)
virtual bool accept();