PD: Add template helper functions to safely access feature or view provider

In subclasses of TaskFeatureParameters use the new helper functions and check for null pointer. This fixes #15453
This commit is contained in:
wmayer
2024-07-18 13:40:08 +02:00
parent b1029bc682
commit 010a36df30
13 changed files with 836 additions and 747 deletions

View File

@@ -68,7 +68,7 @@ TaskExtrudeParameters::~TaskExtrudeParameters() = default;
void TaskExtrudeParameters::setupDialog()
{
// Get the feature data
PartDesign::FeatureExtrude* extrude = static_cast<PartDesign::FeatureExtrude*>(vp->getObject());
auto extrude = getObject<PartDesign::FeatureExtrude>();
Base::Quantity l = extrude->Length.getQuantityValue();
Base::Quantity l2 = extrude->Length2.getQuantityValue();
Base::Quantity off = extrude->Offset.getQuantityValue();
@@ -268,7 +268,7 @@ void PartDesignGui::TaskExtrudeParameters::onUnselectShapeFacesTrigger()
auto selected = ui->listWidgetReferences->selectedItems();
auto faces = getShapeFaces();
auto extrude = static_cast<PartDesign::FeatureExtrude*>(vp->getObject());
auto extrude = getObject<PartDesign::FeatureExtrude>();
faces.erase(std::remove_if(faces.begin(), faces.end(), [selected](const std::string &face) {
for (auto &item : selected) {
@@ -307,13 +307,13 @@ void TaskExtrudeParameters::setSelectionMode(SelectionMode mode)
break;
case SelectShapeFaces:
onSelectReference(AllowSelection::FACE);
static_cast<ViewProviderExtrude*>(vp)->highlightShapeFaces(getShapeFaces());
getViewObject<ViewProviderExtrude>()->highlightShapeFaces(getShapeFaces());
break;
case SelectReferenceAxis:
onSelectReference(AllowSelection::EDGE | AllowSelection::PLANAR | AllowSelection::CIRCLE);
break;
default:
static_cast<ViewProviderExtrude*>(vp)->highlightShapeFaces({});
getViewObject<ViewProviderExtrude>()->highlightShapeFaces({});
onSelectReference(AllowSelection::NONE);
}
}
@@ -364,7 +364,7 @@ void TaskExtrudeParameters::selectedReferenceAxis(const Gui::SelectionChanges& m
std::vector<std::string> edge;
App::DocumentObject* selObj;
if (getReferencedSelection(vp->getObject(), msg, selObj, edge) && selObj) {
if (getReferencedSelection(getObject(), msg, selObj, edge) && selObj) {
setSelectionMode(None);
propReferenceAxis->setValue(selObj, edge);
@@ -377,7 +377,7 @@ void TaskExtrudeParameters::selectedReferenceAxis(const Gui::SelectionChanges& m
void TaskExtrudeParameters::selectedShapeFace(const Gui::SelectionChanges& msg)
{
auto extrude = static_cast<PartDesign::FeatureExtrude*>(vp->getObject());
auto extrude = getObject<PartDesign::FeatureExtrude>();
auto document = extrude->getDocument();
if (strcmp(msg.pDocName, document->getName()) != 0) {
@@ -436,7 +436,7 @@ void PartDesignGui::TaskExtrudeParameters::selectedFace(const Gui::SelectionChan
void PartDesignGui::TaskExtrudeParameters::selectedShape(const Gui::SelectionChanges& msg)
{
auto extrude = static_cast<PartDesign::FeatureExtrude*>(vp->getObject());
auto extrude = getObject<PartDesign::FeatureExtrude>();
auto document = extrude->getDocument();
if (strcmp(msg.pDocName, document->getName()) != 0) {
@@ -472,12 +472,13 @@ void TaskExtrudeParameters::updateShapeName()
{
QSignalBlocker block(ui->lineShapeName);
auto extrude = static_cast<PartDesign::FeatureExtrude*>(vp->getObject());
auto extrude = getObject<PartDesign::FeatureExtrude>();
auto shape = extrude->UpToShape.getValue();
if (shape) {
ui->lineShapeName->setText(QString::fromStdString(shape->getFullName()));
} else {
}
else {
ui->lineShapeName->setText({});
ui->lineShapeName->setPlaceholderText(tr("No shape selected"));
}
@@ -493,7 +494,7 @@ void TaskExtrudeParameters::updateShapeFaces()
}
if (selectionMode == SelectShapeFaces) {
static_cast<ViewProviderExtrude*>(vp)->highlightShapeFaces(faces);
getViewObject<ViewProviderExtrude>()->highlightShapeFaces(faces);
}
}
@@ -501,7 +502,7 @@ std::vector<std::string> PartDesignGui::TaskExtrudeParameters::getShapeFaces()
{
std::vector<std::string> faces;
auto extrude = static_cast<PartDesign::FeatureExtrude*>(vp->getObject());
auto extrude = getObject<PartDesign::FeatureExtrude>();
auto allRefs = extrude->UpToShape.getSubValues();
std::copy_if(
@@ -515,37 +516,42 @@ std::vector<std::string> PartDesignGui::TaskExtrudeParameters::getShapeFaces()
void TaskExtrudeParameters::onLengthChanged(double len)
{
PartDesign::FeatureExtrude* extrude = static_cast<PartDesign::FeatureExtrude*>(vp->getObject());
extrude->Length.setValue(len);
tryRecomputeFeature();
if (auto extrude = getObject<PartDesign::FeatureExtrude>()) {
extrude->Length.setValue(len);
tryRecomputeFeature();
}
}
void TaskExtrudeParameters::onLength2Changed(double len)
{
PartDesign::FeatureExtrude* extrude = static_cast<PartDesign::FeatureExtrude*>(vp->getObject());
extrude->Length2.setValue(len);
tryRecomputeFeature();
if (auto extrude = getObject<PartDesign::FeatureExtrude>()) {
extrude->Length2.setValue(len);
tryRecomputeFeature();
}
}
void TaskExtrudeParameters::onOffsetChanged(double len)
{
PartDesign::FeatureExtrude* extrude = static_cast<PartDesign::FeatureExtrude*>(vp->getObject());
extrude->Offset.setValue(len);
tryRecomputeFeature();
if (auto extrude = getObject<PartDesign::FeatureExtrude>()) {
extrude->Offset.setValue(len);
tryRecomputeFeature();
}
}
void TaskExtrudeParameters::onTaperChanged(double angle)
{
PartDesign::FeatureExtrude* extrude = static_cast<PartDesign::FeatureExtrude*>(vp->getObject());
extrude->TaperAngle.setValue(angle);
tryRecomputeFeature();
if (auto extrude = getObject<PartDesign::FeatureExtrude>()) {
extrude->TaperAngle.setValue(angle);
tryRecomputeFeature();
}
}
void TaskExtrudeParameters::onTaper2Changed(double angle)
{
PartDesign::FeatureExtrude* extrude = static_cast<PartDesign::FeatureExtrude*>(vp->getObject());
extrude->TaperAngle2.setValue(angle);
tryRecomputeFeature();
if (auto extrude = getObject<PartDesign::FeatureExtrude>()) {
extrude->TaperAngle2.setValue(angle);
tryRecomputeFeature();
}
}
bool TaskExtrudeParameters::hasProfileFace(PartDesign::ProfileBased* profile) const
@@ -572,7 +578,7 @@ void TaskExtrudeParameters::fillDirectionCombo()
ui->directionCB->clear();
// we can have sketches or faces
// for sketches just get the sketch normal
PartDesign::ProfileBased* pcFeat = static_cast<PartDesign::ProfileBased*>(vp->getObject());
auto pcFeat = getObject<PartDesign::ProfileBased>();
Part::Part2DObject* pcSketch = dynamic_cast<Part::Part2DObject*>(pcFeat->Profile.getValue());
// for faces we test if it is verified and if we can get its normal
if (!pcSketch) {
@@ -622,7 +628,7 @@ void TaskExtrudeParameters::fillDirectionCombo()
}
// highlight either current index or set custom direction
PartDesign::FeatureExtrude* extrude = static_cast<PartDesign::FeatureExtrude*>(vp->getObject());
auto extrude = getObject<PartDesign::FeatureExtrude>();
bool hasCustom = extrude->UseCustomVector.getValue();
if (indexOfCurrent != -1 && !hasCustom)
ui->directionCB->setCurrentIndex(indexOfCurrent);
@@ -745,8 +751,6 @@ void TaskExtrudeParameters::setCheckboxes(Mode mode, Type type)
void TaskExtrudeParameters::onDirectionCBChanged(int num)
{
PartDesign::FeatureExtrude* extrude = static_cast<PartDesign::FeatureExtrude*>(vp->getObject());
if (axesInList.empty())
return;
@@ -766,7 +770,7 @@ void TaskExtrudeParameters::onDirectionCBChanged(int num)
setSelectionMode(SelectReferenceAxis);
setDirectionMode(num);
}
else {
else if (auto extrude = getObject<PartDesign::FeatureExtrude>()) {
if (lnk.getValue()) {
if (!extrude->getDocument()->isIn(lnk.getValue())) {
Base::Console().Error("Object was deleted\n");
@@ -787,9 +791,10 @@ void TaskExtrudeParameters::onDirectionCBChanged(int num)
void TaskExtrudeParameters::onAlongSketchNormalChanged(bool on)
{
PartDesign::FeatureExtrude* extrude = static_cast<PartDesign::FeatureExtrude*>(vp->getObject());
extrude->AlongSketchNormal.setValue(on);
tryRecomputeFeature();
if (auto extrude = getObject<PartDesign::FeatureExtrude>()) {
extrude->AlongSketchNormal.setValue(on);
tryRecomputeFeature();
}
}
void TaskExtrudeParameters::onDirectionToggled(bool on)
@@ -808,45 +813,55 @@ void PartDesignGui::TaskExtrudeParameters::onAllFacesToggled(bool on)
ui->buttonShapeFace->setChecked(false);
if (on) {
auto extrude = static_cast<PartDesign::FeatureExtrude*>(vp->getObject());
extrude->UpToShape.setValue(extrude->UpToShape.getValue());
if (auto extrude = getObject<PartDesign::FeatureExtrude>()) {
extrude->UpToShape.setValue(extrude->UpToShape.getValue());
updateShapeFaces();
updateShapeFaces();
tryRecomputeFeature();
tryRecomputeFeature();
}
}
}
void TaskExtrudeParameters::onXDirectionEditChanged(double len)
{
PartDesign::FeatureExtrude* extrude = static_cast<PartDesign::FeatureExtrude*>(vp->getObject());
extrude->Direction.setValue(len, extrude->Direction.getValue().y, extrude->Direction.getValue().z);
tryRecomputeFeature();
// checking for case of a null vector is done in FeatureExtrude.cpp
// if there was a null vector, the normal vector of the sketch is used.
// therefore the vector component edits must be updated
updateDirectionEdits();
if (auto extrude = getObject<PartDesign::FeatureExtrude>()) {
extrude->Direction.setValue(len,
extrude->Direction.getValue().y,
extrude->Direction.getValue().z);
tryRecomputeFeature();
// checking for case of a null vector is done in FeatureExtrude.cpp
// if there was a null vector, the normal vector of the sketch is used.
// therefore the vector component edits must be updated
updateDirectionEdits();
}
}
void TaskExtrudeParameters::onYDirectionEditChanged(double len)
{
PartDesign::FeatureExtrude* extrude = static_cast<PartDesign::FeatureExtrude*>(vp->getObject());
extrude->Direction.setValue(extrude->Direction.getValue().x, len, extrude->Direction.getValue().z);
tryRecomputeFeature();
updateDirectionEdits();
if (auto extrude = getObject<PartDesign::FeatureExtrude>()) {
extrude->Direction.setValue(extrude->Direction.getValue().x,
len,
extrude->Direction.getValue().z);
tryRecomputeFeature();
updateDirectionEdits();
}
}
void TaskExtrudeParameters::onZDirectionEditChanged(double len)
{
PartDesign::FeatureExtrude* extrude = static_cast<PartDesign::FeatureExtrude*>(vp->getObject());
extrude->Direction.setValue(extrude->Direction.getValue().x, extrude->Direction.getValue().y, len);
tryRecomputeFeature();
updateDirectionEdits();
if (auto extrude = getObject<PartDesign::FeatureExtrude>()) {
extrude->Direction.setValue(extrude->Direction.getValue().x,
extrude->Direction.getValue().y,
len);
tryRecomputeFeature();
updateDirectionEdits();
}
}
void TaskExtrudeParameters::updateDirectionEdits()
{
PartDesign::FeatureExtrude* extrude = static_cast<PartDesign::FeatureExtrude*>(vp->getObject());
auto extrude = getObject<PartDesign::FeatureExtrude>();
// we don't want to execute the onChanged edits, but just update their contents
QSignalBlocker xdir(ui->XDirectionEdit);
QSignalBlocker ydir(ui->YDirectionEdit);
@@ -858,7 +873,11 @@ void TaskExtrudeParameters::updateDirectionEdits()
void TaskExtrudeParameters::setDirectionMode(int index)
{
PartDesign::FeatureExtrude* extrude = static_cast<PartDesign::FeatureExtrude*>(vp->getObject());
auto extrude = getObject<PartDesign::FeatureExtrude>();
if (!extrude) {
return;
}
// disable AlongSketchNormal when the direction is already normal
if (index == DirectionModes::Normal)
ui->checkBoxAlongDirection->setEnabled(false);
@@ -890,20 +909,22 @@ void TaskExtrudeParameters::setDirectionMode(int index)
void TaskExtrudeParameters::onMidplaneChanged(bool on)
{
PartDesign::FeatureExtrude* extrude = static_cast<PartDesign::FeatureExtrude*>(vp->getObject());
extrude->Midplane.setValue(on);
ui->checkBoxReversed->setEnabled(!on);
tryRecomputeFeature();
if (auto extrude = getObject<PartDesign::FeatureExtrude>()) {
extrude->Midplane.setValue(on);
ui->checkBoxReversed->setEnabled(!on);
tryRecomputeFeature();
}
}
void TaskExtrudeParameters::onReversedChanged(bool on)
{
PartDesign::FeatureExtrude* extrude = static_cast<PartDesign::FeatureExtrude*>(vp->getObject());
extrude->Reversed.setValue(on);
ui->checkBoxMidplane->setEnabled(!on);
// update the direction
tryRecomputeFeature();
updateDirectionEdits();
if (auto extrude = getObject<PartDesign::FeatureExtrude>()) {
extrude->Reversed.setValue(on);
ui->checkBoxMidplane->setEnabled(!on);
// update the direction
tryRecomputeFeature();
updateDirectionEdits();
}
}
void TaskExtrudeParameters::getReferenceAxis(App::DocumentObject*& obj, std::vector<std::string>& sub) const
@@ -919,7 +940,7 @@ void TaskExtrudeParameters::getReferenceAxis(App::DocumentObject*& obj, std::vec
sub.clear();
}
else {
PartDesign::ProfileBased* pcDirection = static_cast<PartDesign::ProfileBased*>(vp->getObject());
auto pcDirection = getObject<PartDesign::ProfileBased>();
if (!pcDirection->getDocument()->isIn(lnk.getValue()))
throw Base::RuntimeError("Object was deleted");
@@ -1114,7 +1135,7 @@ void TaskExtrudeParameters::saveHistory()
void TaskExtrudeParameters::applyParameters(QString facename)
{
auto obj = vp->getObject();
auto obj = getObject();
ui->lengthEdit->apply();
ui->lengthEdit2->apply();

View File

@@ -45,9 +45,10 @@ using namespace Gui;
*********************************************************************/
TaskFeatureParameters::TaskFeatureParameters(PartDesignGui::ViewProvider *vp, QWidget *parent,
const std::string& pixmapname, const QString& parname)
: TaskBox(Gui::BitmapFactory().pixmap(pixmapname.c_str()),parname,true, parent),
vp(vp), blockUpdate(false)
const std::string& pixmapname, const QString& parname)
: TaskBox(Gui::BitmapFactory().pixmap(pixmapname.c_str()), parname, true, parent)
, vp(vp)
, blockUpdate(false)
{
Gui::Document* doc = vp->getDocument();
this->attachDocument(doc);
@@ -55,8 +56,9 @@ TaskFeatureParameters::TaskFeatureParameters(PartDesignGui::ViewProvider *vp, QW
void TaskFeatureParameters::slotDeletedObject(const Gui::ViewProviderDocumentObject& Obj)
{
if (this->vp == &Obj)
if (this->vp == &Obj) {
this->vp = nullptr;
}
}
void TaskFeatureParameters::onUpdateView(bool on)
@@ -68,9 +70,9 @@ void TaskFeatureParameters::onUpdateView(bool on)
void TaskFeatureParameters::recomputeFeature()
{
if (!blockUpdate) {
App::DocumentObject* obj = vp->getObject ();
App::DocumentObject* obj = getObject();
assert (obj);
obj->getDocument()->recomputeFeature ( obj );
obj->getDocument()->recomputeFeature (obj);
}
}
@@ -78,15 +80,16 @@ void TaskFeatureParameters::recomputeFeature()
* Task Dialog *
*********************************************************************/
TaskDlgFeatureParameters::TaskDlgFeatureParameters(PartDesignGui::ViewProvider *vp)
: TaskDialog(),vp(vp)
: vp(vp)
{
assert(vp);
}
TaskDlgFeatureParameters::~TaskDlgFeatureParameters() = default;
bool TaskDlgFeatureParameters::accept() {
App::DocumentObject* feature = vp->getObject();
bool TaskDlgFeatureParameters::accept()
{
App::DocumentObject* feature = getObject();
try {
// Iterate over parameter dialogs and apply all parameters from them
@@ -107,7 +110,7 @@ bool TaskDlgFeatureParameters::accept() {
Gui::cmdAppDocument(feature, "recompute()");
if (!feature->isValid()) {
throw Base::RuntimeError(vp->getObject()->getStatusString());
throw Base::RuntimeError(getObject()->getStatusString());
}
App::DocumentObject* previous = static_cast<PartDesign::Feature*>(feature)->getBaseObject(/* silent = */ true );
@@ -136,7 +139,7 @@ bool TaskDlgFeatureParameters::accept() {
bool TaskDlgFeatureParameters::reject()
{
PartDesign::Feature* feature = static_cast<PartDesign::Feature*>(vp->getObject());
auto feature = getObject<PartDesign::Feature>();
App::DocumentObjectWeakPtrT weakptr(feature);
App::Document* document = feature->getDocument();

View File

@@ -24,6 +24,7 @@
#define TASKFEATUREPARAMETERS_H_NAHKE2YZ
#include <type_traits>
#include <Gui/TaskView/TaskDialog.h>
#include <Gui/TaskView/TaskView.h>
#include <Gui/DocumentObserver.h>
@@ -102,12 +103,8 @@ protected:
blockUpdate = value;
}
protected:
PartDesignGui::ViewProvider *vp;
/// Lock updateUI(), applying changes to the underlying feature and calling recomputeFeature()
private:
PartDesignGui::ViewProvider *vp;
bool blockUpdate;
};

View File

@@ -74,7 +74,7 @@ TaskHelixParameters::TaskHelixParameters(PartDesignGui::ViewProviderHelix* Helix
void TaskHelixParameters::initializeHelix()
{
PartDesign::Helix* helix = static_cast<PartDesign::Helix*>(vp->getObject());
auto helix = getObject<PartDesign::Helix>();
if (!(helix->HasBeenEdited).getValue()) {
helix->proposeParameters();
recomputeFeature();
@@ -83,7 +83,7 @@ void TaskHelixParameters::initializeHelix()
void TaskHelixParameters::assignProperties()
{
PartDesign::Helix* helix = static_cast<PartDesign::Helix*>(vp->getObject());
auto helix = getObject<PartDesign::Helix>();
propAngle = &(helix->Angle);
propGrowth = &(helix->Growth);
propPitch = &(helix->Pitch);
@@ -123,7 +123,7 @@ void TaskHelixParameters::setValuesFromProperties()
void TaskHelixParameters::bindProperties()
{
PartDesign::Helix* helix = static_cast<PartDesign::Helix*>(vp->getObject());
auto helix = getObject<PartDesign::Helix>();
ui->pitch->bind(helix->Pitch);
ui->height->bind(helix->Height);
ui->turns->bind(helix->Turns);
@@ -162,8 +162,7 @@ void TaskHelixParameters::connectSlots()
void TaskHelixParameters::showCoordinateAxes()
{
//show the parts coordinate system axis for selection
PartDesign::Body* body = PartDesign::Body::findBodyOf(vp->getObject());
if (body) {
if (PartDesign::Body* body = PartDesign::Body::findBodyOf(getObject())) {
try {
App::Origin* origin = body->getOrigin();
ViewProviderOrigin* vpOrigin;
@@ -205,26 +204,25 @@ void TaskHelixParameters::fillAxisCombo(bool forceRefill)
void TaskHelixParameters::addSketchAxes()
{
PartDesign::ProfileBased* pcFeat = static_cast<PartDesign::ProfileBased*>(vp->getObject());
Part::Part2DObject* pcSketch = dynamic_cast<Part::Part2DObject*>(pcFeat->Profile.getValue());
if (pcSketch) {
addAxisToCombo(pcSketch, "N_Axis", tr("Normal sketch axis"));
addAxisToCombo(pcSketch, "V_Axis", tr("Vertical sketch axis"));
addAxisToCombo(pcSketch, "H_Axis", tr("Horizontal sketch axis"));
for (int i = 0; i < pcSketch->getAxisCount(); i++) {
auto profile = getObject<PartDesign::ProfileBased>();
auto sketch = dynamic_cast<Part::Part2DObject*>(profile->Profile.getValue());
if (sketch) {
addAxisToCombo(sketch, "N_Axis", tr("Normal sketch axis"));
addAxisToCombo(sketch, "V_Axis", tr("Vertical sketch axis"));
addAxisToCombo(sketch, "H_Axis", tr("Horizontal sketch axis"));
for (int i = 0; i < sketch->getAxisCount(); i++) {
QString itemText = tr("Construction line %1").arg(i + 1);
std::stringstream sub;
sub << "Axis" << i;
addAxisToCombo(pcSketch, sub.str(), itemText);
addAxisToCombo(sketch, sub.str(), itemText);
}
}
}
void TaskHelixParameters::addPartAxes()
{
PartDesign::ProfileBased* pcFeat = static_cast<PartDesign::ProfileBased*>(vp->getObject());
PartDesign::Body* body = PartDesign::Body::findBodyOf(pcFeat);
if (body) {
auto profile = getObject<PartDesign::ProfileBased>();
if (PartDesign::Body* body = PartDesign::Body::findBodyOf(profile)) {
try {
App::Origin* orig = body->getOrigin();
addAxisToCombo(orig->getX(), "", tr("Base X axis"));
@@ -271,11 +269,11 @@ void TaskHelixParameters::addAxisToCombo(App::DocumentObject* linkObj, std::stri
void TaskHelixParameters::updateStatus()
{
auto pcHelix = static_cast<PartDesign::Helix*>(vp->getObject());
auto status = std::string(pcHelix->getStatusString());
auto helix = getObject<PartDesign::Helix>();
auto status = std::string(helix->getStatusString());
QString translatedStatus;
if (status.compare("Valid") == 0 || status.compare("Touched") == 0) {
if (pcHelix->safePitch() > pcHelix->Pitch.getValue()) {
if (helix->safePitch() > helix->Pitch.getValue()) {
translatedStatus = tr("Warning: helix might be self intersecting");
}
}
@@ -303,8 +301,8 @@ void TaskHelixParameters::adaptVisibilityToMode()
bool isAngleVisible = false;
bool isGrowthVisible = false;
auto pcHelix = static_cast<PartDesign::Helix*>(vp->getObject());
if (pcHelix->getAddSubType() == PartDesign::FeatureAddSub::Subtractive)
auto helix = getObject<PartDesign::Helix>();
if (helix->getAddSubType() == PartDesign::FeatureAddSub::Subtractive)
isOutsideVisible = true;
HelixMode mode = static_cast<HelixMode>(propMode->getValue());
@@ -352,47 +350,48 @@ void TaskHelixParameters::adaptVisibilityToMode()
void TaskHelixParameters::assignToolTipsFromPropertyDocs()
{
auto pcHelix = static_cast<PartDesign::Helix*>(vp->getObject());
auto helix = getObject<PartDesign::Helix>();
const char* propCategory = "App::Property"; // cf. https://tracker.freecad.org/view.php?id=0002524
QString toolTip;
// Beware that "Axis" in the GUI actually represents the property "ReferenceAxis"!
// The property "Axis" holds only the directional part of the reference axis and has no corresponding GUI element.
toolTip = QApplication::translate(propCategory, pcHelix->ReferenceAxis.getDocumentation());
// The property "Axis" holds only the directional part of the reference axis and has no
// corresponding GUI element.
toolTip = QApplication::translate(propCategory, helix->ReferenceAxis.getDocumentation());
ui->axis->setToolTip(toolTip);
ui->labelAxis->setToolTip(toolTip);
toolTip = QApplication::translate(propCategory, pcHelix->Mode.getDocumentation());
toolTip = QApplication::translate(propCategory, helix->Mode.getDocumentation());
ui->inputMode->setToolTip(toolTip);
ui->labelInputMode->setToolTip(toolTip);
toolTip = QApplication::translate(propCategory, pcHelix->Pitch.getDocumentation());
toolTip = QApplication::translate(propCategory, helix->Pitch.getDocumentation());
ui->pitch->setToolTip(toolTip);
ui->labelPitch->setToolTip(toolTip);
toolTip = QApplication::translate(propCategory, pcHelix->Height.getDocumentation());
toolTip = QApplication::translate(propCategory, helix->Height.getDocumentation());
ui->height->setToolTip(toolTip);
ui->labelHeight->setToolTip(toolTip);
toolTip = QApplication::translate(propCategory, pcHelix->Turns.getDocumentation());
toolTip = QApplication::translate(propCategory, helix->Turns.getDocumentation());
ui->turns->setToolTip(toolTip);
ui->labelTurns->setToolTip(toolTip);
toolTip = QApplication::translate(propCategory, pcHelix->Angle.getDocumentation());
toolTip = QApplication::translate(propCategory, helix->Angle.getDocumentation());
ui->coneAngle->setToolTip(toolTip);
ui->labelConeAngle->setToolTip(toolTip);
toolTip = QApplication::translate(propCategory, pcHelix->Growth.getDocumentation());
toolTip = QApplication::translate(propCategory, helix->Growth.getDocumentation());
ui->growth->setToolTip(toolTip);
ui->labelGrowth->setToolTip(toolTip);
toolTip = QApplication::translate(propCategory, pcHelix->LeftHanded.getDocumentation());
toolTip = QApplication::translate(propCategory, helix->LeftHanded.getDocumentation());
ui->checkBoxLeftHanded->setToolTip(toolTip);
toolTip = QApplication::translate(propCategory, pcHelix->Reversed.getDocumentation());
toolTip = QApplication::translate(propCategory, helix->Reversed.getDocumentation());
ui->checkBoxReversed->setToolTip(toolTip);
toolTip = QApplication::translate(propCategory, pcHelix->Outside.getDocumentation());
toolTip = QApplication::translate(propCategory, helix->Outside.getDocumentation());
ui->checkBoxOutside->setToolTip(toolTip);
}
@@ -400,8 +399,8 @@ void TaskHelixParameters::onSelectionChanged(const Gui::SelectionChanges& msg)
{
if (msg.Type == Gui::SelectionChanges::AddSelection) {
std::vector<std::string> axis;
App::DocumentObject* selObj;
if (getReferencedSelection(vp->getObject(), msg, selObj, axis) && selObj) {
App::DocumentObject* selObj {};
if (getReferencedSelection(getObject(), msg, selObj, axis) && selObj) {
exitSelectionMode();
propReferenceAxis->setValue(selObj, axis);
recomputeFeature();
@@ -412,42 +411,52 @@ void TaskHelixParameters::onSelectionChanged(const Gui::SelectionChanges& msg)
void TaskHelixParameters::onPitchChanged(double len)
{
propPitch->setValue(len);
recomputeFeature();
updateUI();
if (getObject()) {
propPitch->setValue(len);
recomputeFeature();
updateUI();
}
}
void TaskHelixParameters::onHeightChanged(double len)
{
propHeight->setValue(len);
recomputeFeature();
updateUI();
if (getObject()) {
propHeight->setValue(len);
recomputeFeature();
updateUI();
}
}
void TaskHelixParameters::onTurnsChanged(double len)
{
propTurns->setValue(len);
recomputeFeature();
updateUI();
if (getObject()) {
propTurns->setValue(len);
recomputeFeature();
updateUI();
}
}
void TaskHelixParameters::onAngleChanged(double len)
{
propAngle->setValue(len);
recomputeFeature();
updateUI();
if (getObject()) {
propAngle->setValue(len);
recomputeFeature();
updateUI();
}
}
void TaskHelixParameters::onGrowthChanged(double len)
{
propGrowth->setValue(len);
recomputeFeature();
updateUI();
if (getObject()) {
propGrowth->setValue(len);
recomputeFeature();
updateUI();
}
}
void TaskHelixParameters::onAxisChanged(int num)
{
PartDesign::ProfileBased* pcHelix = static_cast<PartDesign::ProfileBased*>(vp->getObject());
auto helix = getObject<PartDesign::ProfileBased>();
if (axesInList.empty())
return;
@@ -462,7 +471,7 @@ void TaskHelixParameters::onAxisChanged(int num)
if (!lnk.getValue()) {
// enter reference selection mode
// assure the sketch is visible
if (auto sketch = dynamic_cast<Part::Part2DObject *>(pcHelix->Profile.getValue())) {
if (auto sketch = dynamic_cast<Part::Part2DObject *>(helix->Profile.getValue())) {
Gui::cmdAppObjectShow(sketch);
}
TaskSketchBasedParameters::onSelectReference(
@@ -472,7 +481,7 @@ void TaskHelixParameters::onAxisChanged(int num)
return;
}
else {
if (!pcHelix->getDocument()->isIn(lnk.getValue())) {
if (!helix->getDocument()->isIn(lnk.getValue())) {
Base::Console().Error("Object was deleted\n");
return;
}
@@ -525,23 +534,29 @@ void TaskHelixParameters::onModeChanged(int index)
void TaskHelixParameters::onLeftHandedChanged(bool on)
{
propLeftHanded->setValue(on);
recomputeFeature();
updateUI();
if (getObject()) {
propLeftHanded->setValue(on);
recomputeFeature();
updateUI();
}
}
void TaskHelixParameters::onReversedChanged(bool on)
{
propReversed->setValue(on);
recomputeFeature();
updateUI();
if (getObject()) {
propReversed->setValue(on);
recomputeFeature();
updateUI();
}
}
void TaskHelixParameters::onOutsideChanged(bool on)
{
propOutside->setValue(on);
recomputeFeature();
updateUI();
if (getObject()) {
propOutside->setValue(on);
recomputeFeature();
updateUI();
}
}
@@ -549,10 +564,11 @@ TaskHelixParameters::~TaskHelixParameters()
{
try {
//hide the parts coordinate system axis for selection
PartDesign::Body* body = vp ? PartDesign::Body::findBodyOf(vp->getObject()) : nullptr;
auto obj = getObject();
PartDesign::Body* body = obj ? PartDesign::Body::findBodyOf(obj) : nullptr;
if (body) {
App::Origin* origin = body->getOrigin();
ViewProviderOrigin* vpOrigin;
ViewProviderOrigin* vpOrigin {};
vpOrigin = static_cast<ViewProviderOrigin*>(Gui::Application::Instance->getViewProvider(origin));
vpOrigin->resetTemporaryVisibility();
}
@@ -585,8 +601,9 @@ void TaskHelixParameters::changeEvent(QEvent* e)
void TaskHelixParameters::getReferenceAxis(App::DocumentObject*& obj, std::vector<std::string>& sub) const
{
if (axesInList.empty())
if (axesInList.empty()) {
throw Base::RuntimeError("Not initialized!");
}
int num = ui->axis->currentIndex();
const App::PropertyLinkSub& lnk = *(axesInList.at(num));
@@ -594,8 +611,8 @@ void TaskHelixParameters::getReferenceAxis(App::DocumentObject*& obj, std::vecto
throw Base::RuntimeError("Still in reference selection mode; reference wasn't selected yet");
}
else {
PartDesign::ProfileBased* pcRevolution = static_cast<PartDesign::ProfileBased*>(vp->getObject());
if (!pcRevolution->getDocument()->isIn(lnk.getValue())) {
auto revolution = getObject<PartDesign::ProfileBased>();
if (!revolution->getDocument()->isIn(lnk.getValue())) {
throw Base::RuntimeError("Object was deleted");
}
@@ -617,40 +634,42 @@ bool TaskHelixParameters::showPreview(PartDesign::Helix* helix)
void TaskHelixParameters::startReferenceSelection(App::DocumentObject* profile, App::DocumentObject* base)
{
PartDesign::Helix* pcHelix = dynamic_cast<PartDesign::Helix*>(vp->getObject());
if (pcHelix && showPreview(pcHelix)) {
Gui::Document* doc = vp->getDocument();
if (doc) {
doc->setHide(profile->getNameInDocument());
if (auto helix = getObject<PartDesign::Helix>()) {
if (helix && showPreview(helix)) {
Gui::Document* doc = getGuiDocument();
if (doc) {
doc->setHide(profile->getNameInDocument());
}
}
else {
TaskSketchBasedParameters::startReferenceSelection(profile, base);
}
}
else {
TaskSketchBasedParameters::startReferenceSelection(profile, base);
}
}
void TaskHelixParameters::finishReferenceSelection(App::DocumentObject* profile, App::DocumentObject* base)
{
PartDesign::Helix* pcHelix = dynamic_cast<PartDesign::Helix*>(vp->getObject());
if (pcHelix && showPreview(pcHelix)) {
Gui::Document* doc = vp->getDocument();
if (doc) {
doc->setShow(profile->getNameInDocument());
if (auto helix = getObject<PartDesign::Helix>()) {
if (helix && showPreview(helix)) {
Gui::Document* doc = getGuiDocument();
if (doc) {
doc->setShow(profile->getNameInDocument());
}
}
else {
TaskSketchBasedParameters::finishReferenceSelection(profile, base);
}
}
else {
TaskSketchBasedParameters::finishReferenceSelection(profile, base);
}
}
// this is used for logging the command fully when recording macros
void TaskHelixParameters::apply()
void TaskHelixParameters::apply() // NOLINT
{
std::vector<std::string> sub;
App::DocumentObject* obj;
App::DocumentObject* obj {};
getReferenceAxis(obj, sub);
std::string axis = buildLinkSingleSubPythonStr(obj, sub);
auto tobj = vp->getObject();
auto tobj = getObject();
FCMD_OBJ_CMD(tobj, "ReferenceAxis = " << axis);
FCMD_OBJ_CMD(tobj, "Mode = " << propMode->getValue());
FCMD_OBJ_CMD(tobj, "Pitch = " << propPitch->getValue());

View File

@@ -51,7 +51,7 @@ namespace sp = std::placeholders;
TaskHoleParameters::TaskHoleParameters(ViewProviderHole* HoleView, QWidget* parent)
: TaskSketchBasedParameters(HoleView, parent, "PartDesign_Hole", tr("Hole parameters"))
, observer(new Observer(this, static_cast<PartDesign::Hole*>(vp->getObject())))
, observer(new Observer(this, getObject<PartDesign::Hole>()))
, isApplying(false)
, ui(new Ui_TaskHoleParameters)
{
@@ -68,7 +68,7 @@ TaskHoleParameters::TaskHoleParameters(ViewProviderHole* HoleView, QWidget* pare
ui->ThreadType->addItem(tr("UTS extra fine profile"), QByteArray("UTS"));
// read values from the hole properties
PartDesign::Hole* pcHole = static_cast<PartDesign::Hole*>(vp->getObject());
auto pcHole = getObject<PartDesign::Hole>();
ui->Threaded->setChecked(pcHole->Threaded.getValue());
ui->Threaded->setDisabled(std::string(pcHole->ThreadType.getValueAsString()) == "None");
@@ -238,7 +238,7 @@ TaskHoleParameters::TaskHoleParameters(ViewProviderHole* HoleView, QWidget* pare
connect(ui->ThreadDepth, qOverload<double>(&Gui::QuantitySpinBox::valueChanged),
this, &TaskHoleParameters::threadDepthChanged);
vp->show();
getViewObject()->show();
ui->Diameter->bind(pcHole->Diameter);
ui->HoleCutDiameter->bind(pcHole->HoleCutDiameter);
@@ -262,7 +262,7 @@ TaskHoleParameters::~TaskHoleParameters() = default;
void TaskHoleParameters::threadedChanged()
{
PartDesign::Hole* pcHole = static_cast<PartDesign::Hole*>(vp->getObject());
auto pcHole = getObject<PartDesign::Hole>();
bool isChecked = ui->Threaded->isChecked();
pcHole->Threaded.setValue(isChecked);
@@ -289,7 +289,7 @@ void TaskHoleParameters::threadedChanged()
void TaskHoleParameters::modelThreadChanged()
{
PartDesign::Hole* pcHole = static_cast<PartDesign::Hole*>(vp->getObject());
auto pcHole = getObject<PartDesign::Hole>();
pcHole->ModelThread.setValue(ui->ModelThread->isChecked());
@@ -316,20 +316,20 @@ void TaskHoleParameters::updateViewChanged(bool isChecked)
void TaskHoleParameters::threadDepthTypeChanged(int index)
{
PartDesign::Hole* pcHole = static_cast<PartDesign::Hole*>(vp->getObject());
pcHole->ThreadDepthType.setValue(index);
ui->ThreadDepth->setEnabled(index == 1);
ui->ThreadDepth->setValue(pcHole->ThreadDepth.getValue());
recomputeFeature();
if (auto hole = getObject<PartDesign::Hole>()) {
hole->ThreadDepthType.setValue(index);
ui->ThreadDepth->setEnabled(index == 1);
ui->ThreadDepth->setValue(hole->ThreadDepth.getValue());
recomputeFeature();
}
}
void TaskHoleParameters::threadDepthChanged(double value)
{
PartDesign::Hole* pcHole = static_cast<PartDesign::Hole*>(vp->getObject());
pcHole->ThreadDepth.setValue(value);
recomputeFeature();
if (auto hole = getObject<PartDesign::Hole>()) {
hole->ThreadDepth.setValue(value);
recomputeFeature();
}
}
void TaskHoleParameters::useCustomThreadClearanceChanged()
@@ -338,26 +338,26 @@ void TaskHoleParameters::useCustomThreadClearanceChanged()
ui->CustomThreadClearance->setEnabled(isChecked);
ui->ThreadClass->setDisabled(isChecked);
PartDesign::Hole* pcHole = static_cast<PartDesign::Hole*>(vp->getObject());
pcHole->UseCustomThreadClearance.setValue(isChecked);
recomputeFeature();
if (auto hole = getObject<PartDesign::Hole>()) {
hole->UseCustomThreadClearance.setValue(isChecked);
recomputeFeature();
}
}
void TaskHoleParameters::customThreadClearanceChanged(double value)
{
PartDesign::Hole* pcHole = static_cast<PartDesign::Hole*>(vp->getObject());
pcHole->CustomThreadClearance.setValue(value);
recomputeFeature();
if (auto hole = getObject<PartDesign::Hole>()) {
hole->CustomThreadClearance.setValue(value);
recomputeFeature();
}
}
void TaskHoleParameters::threadPitchChanged(double value)
{
PartDesign::Hole* pcHole = static_cast<PartDesign::Hole*>(vp->getObject());
pcHole->ThreadPitch.setValue(value);
recomputeFeature();
if (auto hole = getObject<PartDesign::Hole>()) {
hole->ThreadPitch.setValue(value);
recomputeFeature();
}
}
void TaskHoleParameters::holeCutTypeChanged(int index)
@@ -365,30 +365,30 @@ void TaskHoleParameters::holeCutTypeChanged(int index)
if (index < 0)
return;
PartDesign::Hole* pcHole = static_cast<PartDesign::Hole*>(vp->getObject());
auto hole = getObject<PartDesign::Hole>();
// the HoleCutDepth is something different for countersinks and counterbores
// therefore reset it, it will be reset to sensible values by setting the new HoleCutType
pcHole->HoleCutDepth.setValue(0.0);
pcHole->HoleCutType.setValue(index);
hole->HoleCutDepth.setValue(0.0);
hole->HoleCutType.setValue(index);
// when holeCutType was changed, reset HoleCutCustomValues to false because it should
// be a purpose decision to overwrite the normed values
// we will handle the case that there is no normed value later in this routine
ui->HoleCutCustomValues->setChecked(false);
pcHole->HoleCutCustomValues.setValue(false);
hole->HoleCutCustomValues.setValue(false);
// recompute to get the info about the HoleCutType properties
recomputeFeature();
// apply the result to the widgets
ui->HoleCutCustomValues->setDisabled(pcHole->HoleCutCustomValues.isReadOnly());
ui->HoleCutCustomValues->setChecked(pcHole->HoleCutCustomValues.getValue());
ui->HoleCutCustomValues->setDisabled(hole->HoleCutCustomValues.isReadOnly());
ui->HoleCutCustomValues->setChecked(hole->HoleCutCustomValues.getValue());
// HoleCutCustomValues is only enabled for screw definitions
// we must do this after recomputeFeature() because this gives us the info if
// the type is a countersink and thus if HoleCutCountersinkAngle can be enabled
std::string HoleCutTypeString = pcHole->HoleCutType.getValueAsString();
std::string HoleCutTypeString = hole->HoleCutType.getValueAsString();
if (HoleCutTypeString == "None" || HoleCutTypeString == "Counterbore"
|| HoleCutTypeString == "Countersink" || HoleCutTypeString == "Counterdrill") {
ui->HoleCutCustomValues->setEnabled(false);
@@ -408,7 +408,7 @@ void TaskHoleParameters::holeCutTypeChanged(int index)
if (ui->HoleCutCustomValues->isChecked()) {
ui->HoleCutDiameter->setEnabled(true);
ui->HoleCutDepth->setEnabled(true);
if (!pcHole->HoleCutCountersinkAngle.isReadOnly())
if (!hole->HoleCutCountersinkAngle.isReadOnly())
ui->HoleCutCountersinkAngle->setEnabled(true);
}
else {
@@ -422,54 +422,58 @@ void TaskHoleParameters::holeCutTypeChanged(int index)
void TaskHoleParameters::holeCutCustomValuesChanged()
{
PartDesign::Hole* pcHole = static_cast<PartDesign::Hole*>(vp->getObject());
if (auto hole = getObject<PartDesign::Hole>()) {
hole->HoleCutCustomValues.setValue(ui->HoleCutCustomValues->isChecked());
pcHole->HoleCutCustomValues.setValue(ui->HoleCutCustomValues->isChecked());
if (ui->HoleCutCustomValues->isChecked()) {
ui->HoleCutDiameter->setEnabled(true);
ui->HoleCutDepth->setEnabled(true);
if (!hole->HoleCutCountersinkAngle.isReadOnly())
ui->HoleCutCountersinkAngle->setEnabled(true);
}
else {
ui->HoleCutDiameter->setEnabled(false);
ui->HoleCutDepth->setEnabled(false);
ui->HoleCutCountersinkAngle->setEnabled(false);
}
if (ui->HoleCutCustomValues->isChecked()) {
ui->HoleCutDiameter->setEnabled(true);
ui->HoleCutDepth->setEnabled(true);
if (!pcHole->HoleCutCountersinkAngle.isReadOnly())
ui->HoleCutCountersinkAngle->setEnabled(true);
recomputeFeature();
}
else {
ui->HoleCutDiameter->setEnabled(false);
ui->HoleCutDepth->setEnabled(false);
ui->HoleCutCountersinkAngle->setEnabled(false);
}
recomputeFeature();
}
void TaskHoleParameters::holeCutDiameterChanged(double value)
{
PartDesign::Hole* pcHole = static_cast<PartDesign::Hole*>(vp->getObject());
pcHole->HoleCutDiameter.setValue(value);
recomputeFeature();
if (auto hole = getObject<PartDesign::Hole>()) {
hole->HoleCutDiameter.setValue(value);
recomputeFeature();
}
}
void TaskHoleParameters::holeCutDepthChanged(double value)
{
PartDesign::Hole* pcHole = static_cast<PartDesign::Hole*>(vp->getObject());
std::string HoleCutTypeString = pcHole->HoleCutType.getValueAsString();
auto hole = getObject<PartDesign::Hole>();
if (!hole) {
return;
}
std::string HoleCutTypeString = hole->HoleCutType.getValueAsString();
if (ui->HoleCutCountersinkAngle->isEnabled() && HoleCutTypeString != "Counterdrill") {
// we have a countersink and recalculate the HoleCutDiameter
// store current depth
double DepthDifference = value - pcHole->HoleCutDepth.getValue();
double DepthDifference = value - hole->HoleCutDepth.getValue();
// new diameter is the old one + 2 * tan(angle / 2) * DepthDifference
double newDiameter = pcHole->HoleCutDiameter.getValue()
+ 2 * tan(Base::toRadians(pcHole->HoleCutCountersinkAngle.getValue() / 2)) * DepthDifference;
double newDiameter = hole->HoleCutDiameter.getValue()
+ 2 * tan(Base::toRadians(hole->HoleCutCountersinkAngle.getValue() / 2)) * DepthDifference;
// only apply if the result is not smaller than the hole diameter
if (newDiameter > pcHole->Diameter.getValue()) {
pcHole->HoleCutDiameter.setValue(newDiameter);
pcHole->HoleCutDepth.setValue(value);
if (newDiameter > hole->Diameter.getValue()) {
hole->HoleCutDiameter.setValue(newDiameter);
hole->HoleCutDepth.setValue(value);
}
}
else {
pcHole->HoleCutDepth.setValue(value);
hole->HoleCutDepth.setValue(value);
}
recomputeFeature();
@@ -477,20 +481,23 @@ void TaskHoleParameters::holeCutDepthChanged(double value)
void TaskHoleParameters::holeCutCountersinkAngleChanged(double value)
{
PartDesign::Hole* pcHole = static_cast<PartDesign::Hole*>(vp->getObject());
pcHole->HoleCutCountersinkAngle.setValue(value);
recomputeFeature();
if (auto hole = getObject<PartDesign::Hole>()) {
hole->HoleCutCountersinkAngle.setValue(value);
recomputeFeature();
}
}
void TaskHoleParameters::depthChanged(int index)
{
PartDesign::Hole* pcHole = static_cast<PartDesign::Hole*>(vp->getObject());
auto hole = getObject<PartDesign::Hole>();
if (!hole) {
return;
}
pcHole->DepthType.setValue(index);
hole->DepthType.setValue(index);
// disable drill point widgets if not 'Dimension'
if (std::string(pcHole->DepthType.getValueAsString()) == "Dimension") {
if (std::string(hole->DepthType.getValueAsString()) == "Dimension") {
ui->drillPointFlat->setEnabled(true);
ui->drillPointAngled->setEnabled(true);
ui->DrillPointAngle->setEnabled(true);
@@ -504,73 +511,73 @@ void TaskHoleParameters::depthChanged(int index)
}
recomputeFeature();
// enabling must be handled after recompute
ui->ThreadDepth->setEnabled(std::string(pcHole->ThreadDepthType.getValueAsString()) == "Dimension");
ui->ThreadDepth->setEnabled(std::string(hole->ThreadDepthType.getValueAsString()) == "Dimension");
}
void TaskHoleParameters::depthValueChanged(double value)
{
PartDesign::Hole* pcHole = static_cast<PartDesign::Hole*>(vp->getObject());
pcHole->Depth.setValue(value);
recomputeFeature();
if (auto hole = getObject<PartDesign::Hole>()) {
hole->Depth.setValue(value);
recomputeFeature();
}
}
void TaskHoleParameters::drillPointChanged()
{
PartDesign::Hole* pcHole = static_cast<PartDesign::Hole*>(vp->getObject());
if (sender() == ui->drillPointFlat) {
pcHole->DrillPoint.setValue((long)0);
ui->DrillForDepth->setEnabled(false);
if (auto hole = getObject<PartDesign::Hole>()) {
if (sender() == ui->drillPointFlat) {
hole->DrillPoint.setValue(0L);
ui->DrillForDepth->setEnabled(false);
}
else if (sender() == ui->drillPointAngled) {
hole->DrillPoint.setValue(1L);
ui->DrillForDepth->setEnabled(true);
}
else {
assert(0);
}
recomputeFeature();
}
else if (sender() == ui->drillPointAngled) {
pcHole->DrillPoint.setValue((long)1);
ui->DrillForDepth->setEnabled(true);
}
else {
assert(0);
}
recomputeFeature();
}
void TaskHoleParameters::drillPointAngledValueChanged(double value)
{
PartDesign::Hole* pcHole = static_cast<PartDesign::Hole*>(vp->getObject());
pcHole->DrillPointAngle.setValue((double)value);
recomputeFeature();
if (auto hole = getObject<PartDesign::Hole>()) {
hole->DrillPointAngle.setValue(value);
recomputeFeature();
}
}
void TaskHoleParameters::drillForDepthChanged()
{
PartDesign::Hole* pcHole = static_cast<PartDesign::Hole*>(vp->getObject());
pcHole->DrillForDepth.setValue(ui->DrillForDepth->isChecked());
recomputeFeature();
if (auto hole = getObject<PartDesign::Hole>()) {
hole->DrillForDepth.setValue(ui->DrillForDepth->isChecked());
recomputeFeature();
}
}
void TaskHoleParameters::taperedChanged()
{
PartDesign::Hole* pcHole = static_cast<PartDesign::Hole*>(vp->getObject());
pcHole->Tapered.setValue(ui->Tapered->isChecked());
recomputeFeature();
if (auto hole = getObject<PartDesign::Hole>()) {
hole->Tapered.setValue(ui->Tapered->isChecked());
recomputeFeature();
}
}
void TaskHoleParameters::reversedChanged()
{
PartDesign::Hole* pcHole = static_cast<PartDesign::Hole*>(vp->getObject());
pcHole->Reversed.setValue(ui->Reversed->isChecked());
recomputeFeature();
if (auto hole = getObject<PartDesign::Hole>()) {
hole->Reversed.setValue(ui->Reversed->isChecked());
recomputeFeature();
}
}
void TaskHoleParameters::taperedAngleChanged(double value)
{
PartDesign::Hole* pcHole = static_cast<PartDesign::Hole*>(vp->getObject());
pcHole->TaperedAngle.setValue(value);
recomputeFeature();
if (auto hole = getObject<PartDesign::Hole>()) {
hole->TaperedAngle.setValue(value);
recomputeFeature();
}
}
void TaskHoleParameters::threadTypeChanged(int index)
@@ -578,7 +585,10 @@ void TaskHoleParameters::threadTypeChanged(int index)
if (index < 0)
return;
PartDesign::Hole* pcHole = static_cast<PartDesign::Hole*>(vp->getObject());
auto hole = getObject<PartDesign::Hole>();
if (!hole) {
return;
}
// A typical case is that users change from an ISO profile to another one.
// When they had e.g. the size "M3" in one profile they expect
@@ -596,10 +606,10 @@ void TaskHoleParameters::threadTypeChanged(int index)
QString CutTypeString = ui->HoleCutType->currentText();
// now set the new type, this will reset the comboboxes to item 0
pcHole->ThreadType.setValue(index);
hole->ThreadType.setValue(index);
// Threaded checkbox is meaningless if no thread profile is selected.
ui->Threaded->setDisabled(std::string(pcHole->ThreadType.getValueAsString()) == "None");
ui->Threaded->setDisabled(std::string(hole->ThreadType.getValueAsString()) == "None");
// size and clearance
if (TypeClass == QByteArray("ISO")) {
@@ -654,14 +664,14 @@ void TaskHoleParameters::threadSizeChanged(int index)
if (index < 0)
return;
PartDesign::Hole* pcHole = static_cast<PartDesign::Hole*>(vp->getObject());
if (auto hole = getObject<PartDesign::Hole>()) {
hole->ThreadSize.setValue(index);
recomputeFeature();
pcHole->ThreadSize.setValue(index);
recomputeFeature();
// apply the recompute result to the widgets
ui->HoleCutCustomValues->setDisabled(pcHole->HoleCutCustomValues.isReadOnly());
ui->HoleCutCustomValues->setChecked(pcHole->HoleCutCustomValues.getValue());
// apply the recompute result to the widgets
ui->HoleCutCustomValues->setDisabled(hole->HoleCutCustomValues.isReadOnly());
ui->HoleCutCustomValues->setChecked(hole->HoleCutCustomValues.getValue());
}
}
void TaskHoleParameters::threadClassChanged(int index)
@@ -669,41 +679,41 @@ void TaskHoleParameters::threadClassChanged(int index)
if (index < 0)
return;
PartDesign::Hole* pcHole = static_cast<PartDesign::Hole*>(vp->getObject());
pcHole->ThreadClass.setValue(index);
recomputeFeature();
if (auto hole = getObject<PartDesign::Hole>()) {
hole->ThreadClass.setValue(index);
recomputeFeature();
}
}
void TaskHoleParameters::threadDiameterChanged(double value)
{
PartDesign::Hole* pcHole = static_cast<PartDesign::Hole*>(vp->getObject());
if (auto hole = getObject<PartDesign::Hole>()) {
hole->Diameter.setValue(value);
pcHole->Diameter.setValue(value);
// HoleCutDiameter must not be smaller or equal than the Diameter
ui->HoleCutDiameter->setMinimum(value + 0.1);
// HoleCutDiameter must not be smaller or equal than the Diameter
ui->HoleCutDiameter->setMinimum(value + 0.1);
recomputeFeature();
recomputeFeature();
}
}
void TaskHoleParameters::threadFitChanged(int index)
{
PartDesign::Hole* pcHole = static_cast<PartDesign::Hole*>(vp->getObject());
pcHole->ThreadFit.setValue(index);
recomputeFeature();
if (auto hole = getObject<PartDesign::Hole>()) {
hole->ThreadFit.setValue(index);
recomputeFeature();
}
}
void TaskHoleParameters::threadDirectionChanged()
{
PartDesign::Hole* pcHole = static_cast<PartDesign::Hole*>(vp->getObject());
if (sender() == ui->directionRightHand)
pcHole->ThreadDirection.setValue((long)0);
else
pcHole->ThreadDirection.setValue((long)1);
recomputeFeature();
if (auto hole = getObject<PartDesign::Hole>()) {
if (sender() == ui->directionRightHand)
hole->ThreadDirection.setValue(0L);
else
hole->ThreadDirection.setValue(1L);
recomputeFeature();
}
}
void TaskHoleParameters::changeEvent(QEvent* e)
@@ -716,102 +726,102 @@ void TaskHoleParameters::changeEvent(QEvent* e)
void TaskHoleParameters::changedObject(const App::Document&, const App::Property& Prop)
{
// happens when aborting the command
if (!vp)
auto hole = getObject<PartDesign::Hole>();
if (!hole) {
// happens when aborting the command
return;
PartDesign::Hole* pcHole = static_cast<PartDesign::Hole*>(vp->getObject());
}
bool ro = Prop.isReadOnly();
Base::Console().Log("Parameter %s was updated\n", Prop.getName());
if (&Prop == &pcHole->Threaded) {
if (&Prop == &hole->Threaded) {
ui->Threaded->setEnabled(true);
if (ui->Threaded->isChecked() ^ pcHole->Threaded.getValue()) {
if (ui->Threaded->isChecked() ^ hole->Threaded.getValue()) {
ui->Threaded->blockSignals(true);
ui->Threaded->setChecked(pcHole->Threaded.getValue());
ui->Threaded->setChecked(hole->Threaded.getValue());
ui->Threaded->blockSignals(false);
}
ui->Threaded->setDisabled(ro);
}
else if (&Prop == &pcHole->ThreadType) {
else if (&Prop == &hole->ThreadType) {
ui->ThreadType->setEnabled(true);
ui->ThreadSize->blockSignals(true);
ui->ThreadSize->clear();
std::vector<std::string> cursor = pcHole->ThreadSize.getEnumVector();
std::vector<std::string> cursor = hole->ThreadSize.getEnumVector();
for (const auto& it : cursor) {
ui->ThreadSize->addItem(QString::fromStdString(it));
}
ui->ThreadSize->setCurrentIndex(pcHole->ThreadSize.getValue());
ui->ThreadSize->setCurrentIndex(hole->ThreadSize.getValue());
ui->ThreadSize->blockSignals(false);
// Thread type also updates HoleCutType and ThreadClass
ui->HoleCutType->blockSignals(true);
ui->HoleCutType->clear();
cursor = pcHole->HoleCutType.getEnumVector();
cursor = hole->HoleCutType.getEnumVector();
for (const auto& it: cursor) {
ui->HoleCutType->addItem(QString::fromStdString(it));
}
ui->HoleCutType->setCurrentIndex(pcHole->HoleCutType.getValue());
ui->HoleCutType->setCurrentIndex(hole->HoleCutType.getValue());
ui->HoleCutType->blockSignals(false);
ui->ThreadClass->blockSignals(true);
ui->ThreadClass->clear();
cursor = pcHole->ThreadClass.getEnumVector();
cursor = hole->ThreadClass.getEnumVector();
for (const auto& it : cursor) {
ui->ThreadClass->addItem(QString::fromStdString(it));
}
ui->ThreadClass->setCurrentIndex(pcHole->ThreadClass.getValue());
ui->ThreadClass->setCurrentIndex(hole->ThreadClass.getValue());
ui->ThreadClass->blockSignals(false);
if (ui->ThreadType->currentIndex() != pcHole->ThreadType.getValue()) {
if (ui->ThreadType->currentIndex() != hole->ThreadType.getValue()) {
ui->ThreadType->blockSignals(true);
ui->ThreadType->setCurrentIndex(pcHole->ThreadType.getValue());
ui->ThreadType->setCurrentIndex(hole->ThreadType.getValue());
ui->ThreadType->blockSignals(false);
}
ui->ThreadType->setDisabled(ro);
}
else if (&Prop == &pcHole->ThreadSize) {
else if (&Prop == &hole->ThreadSize) {
ui->ThreadSize->setEnabled(true);
if (ui->ThreadSize->currentIndex() != pcHole->ThreadSize.getValue()) {
if (ui->ThreadSize->currentIndex() != hole->ThreadSize.getValue()) {
ui->ThreadSize->blockSignals(true);
ui->ThreadSize->setCurrentIndex(pcHole->ThreadSize.getValue());
ui->ThreadSize->setCurrentIndex(hole->ThreadSize.getValue());
ui->ThreadSize->blockSignals(false);
}
ui->ThreadSize->setDisabled(ro);
}
else if (&Prop == &pcHole->ThreadClass) {
else if (&Prop == &hole->ThreadClass) {
ui->ThreadClass->setEnabled(true);
if (ui->ThreadClass->currentIndex() != pcHole->ThreadClass.getValue()) {
if (ui->ThreadClass->currentIndex() != hole->ThreadClass.getValue()) {
ui->ThreadClass->blockSignals(true);
ui->ThreadClass->setCurrentIndex(pcHole->ThreadClass.getValue());
ui->ThreadClass->setCurrentIndex(hole->ThreadClass.getValue());
ui->ThreadClass->blockSignals(false);
}
ui->ThreadClass->setDisabled(ro);
}
else if (&Prop == &pcHole->ThreadFit) {
else if (&Prop == &hole->ThreadFit) {
ui->ThreadFit->setEnabled(true);
if (ui->ThreadFit->currentIndex() != pcHole->ThreadFit.getValue()) {
if (ui->ThreadFit->currentIndex() != hole->ThreadFit.getValue()) {
ui->ThreadFit->blockSignals(true);
ui->ThreadFit->setCurrentIndex(pcHole->ThreadFit.getValue());
ui->ThreadFit->setCurrentIndex(hole->ThreadFit.getValue());
ui->ThreadFit->blockSignals(false);
}
ui->ThreadFit->setDisabled(ro);
}
else if (&Prop == &pcHole->Diameter) {
else if (&Prop == &hole->Diameter) {
ui->Diameter->setEnabled(true);
if (ui->Diameter->value().getValue() != pcHole->Diameter.getValue()) {
if (ui->Diameter->value().getValue() != hole->Diameter.getValue()) {
ui->Diameter->blockSignals(true);
ui->Diameter->setValue(pcHole->Diameter.getValue());
ui->Diameter->setValue(hole->Diameter.getValue());
ui->Diameter->blockSignals(false);
}
ui->Diameter->setDisabled(ro);
}
else if (&Prop == &pcHole->ThreadDirection) {
else if (&Prop == &hole->ThreadDirection) {
ui->directionRightHand->setEnabled(true);
ui->directionLeftHand->setEnabled(true);
std::string direction(pcHole->ThreadDirection.getValueAsString());
std::string direction(hole->ThreadDirection.getValueAsString());
if (direction == "Right" && !ui->directionRightHand->isChecked()) {
ui->directionRightHand->blockSignals(true);
ui->directionRightHand->setChecked(true);
@@ -825,64 +835,64 @@ void TaskHoleParameters::changedObject(const App::Document&, const App::Property
ui->directionRightHand->setDisabled(ro);
ui->directionLeftHand->setDisabled(ro);
}
else if (&Prop == &pcHole->HoleCutType) {
else if (&Prop == &hole->HoleCutType) {
ui->HoleCutType->setEnabled(true);
if (ui->HoleCutType->currentIndex() != pcHole->HoleCutType.getValue()) {
if (ui->HoleCutType->currentIndex() != hole->HoleCutType.getValue()) {
ui->HoleCutType->blockSignals(true);
ui->HoleCutType->setCurrentIndex(pcHole->HoleCutType.getValue());
ui->HoleCutType->setCurrentIndex(hole->HoleCutType.getValue());
ui->HoleCutType->blockSignals(false);
}
ui->HoleCutType->setDisabled(ro);
}
else if (&Prop == &pcHole->HoleCutDiameter) {
else if (&Prop == &hole->HoleCutDiameter) {
ui->HoleCutDiameter->setEnabled(true);
if (ui->HoleCutDiameter->value().getValue() != pcHole->HoleCutDiameter.getValue()) {
if (ui->HoleCutDiameter->value().getValue() != hole->HoleCutDiameter.getValue()) {
ui->HoleCutDiameter->blockSignals(true);
ui->HoleCutDiameter->setValue(pcHole->HoleCutDiameter.getValue());
ui->HoleCutDiameter->setValue(hole->HoleCutDiameter.getValue());
ui->HoleCutDiameter->blockSignals(false);
}
ui->HoleCutDiameter->setDisabled(ro);
}
else if (&Prop == &pcHole->HoleCutDepth) {
else if (&Prop == &hole->HoleCutDepth) {
ui->HoleCutDepth->setEnabled(true);
if (ui->HoleCutDepth->value().getValue() != pcHole->HoleCutDepth.getValue()) {
if (ui->HoleCutDepth->value().getValue() != hole->HoleCutDepth.getValue()) {
ui->HoleCutDepth->blockSignals(true);
ui->HoleCutDepth->setValue(pcHole->HoleCutDepth.getValue());
ui->HoleCutDepth->setValue(hole->HoleCutDepth.getValue());
ui->HoleCutDepth->blockSignals(false);
}
ui->HoleCutDepth->setDisabled(ro);
}
else if (&Prop == &pcHole->HoleCutCountersinkAngle) {
else if (&Prop == &hole->HoleCutCountersinkAngle) {
ui->HoleCutCountersinkAngle->setEnabled(true);
if (ui->HoleCutCountersinkAngle->value().getValue() != pcHole->HoleCutCountersinkAngle.getValue()) {
if (ui->HoleCutCountersinkAngle->value().getValue() != hole->HoleCutCountersinkAngle.getValue()) {
ui->HoleCutCountersinkAngle->blockSignals(true);
ui->HoleCutCountersinkAngle->setValue(pcHole->HoleCutCountersinkAngle.getValue());
ui->HoleCutCountersinkAngle->setValue(hole->HoleCutCountersinkAngle.getValue());
ui->HoleCutCountersinkAngle->blockSignals(false);
}
ui->HoleCutCountersinkAngle->setDisabled(ro);
}
else if (&Prop == &pcHole->DepthType) {
else if (&Prop == &hole->DepthType) {
ui->DepthType->setEnabled(true);
if (ui->DepthType->currentIndex() != pcHole->DepthType.getValue()) {
if (ui->DepthType->currentIndex() != hole->DepthType.getValue()) {
ui->DepthType->blockSignals(true);
ui->DepthType->setCurrentIndex(pcHole->DepthType.getValue());
ui->DepthType->setCurrentIndex(hole->DepthType.getValue());
ui->DepthType->blockSignals(false);
}
ui->DepthType->setDisabled(ro);
}
else if (&Prop == &pcHole->Depth) {
else if (&Prop == &hole->Depth) {
ui->Depth->setEnabled(true);
if (ui->Depth->value().getValue() != pcHole->Depth.getValue()) {
if (ui->Depth->value().getValue() != hole->Depth.getValue()) {
ui->Depth->blockSignals(true);
ui->Depth->setValue(pcHole->Depth.getValue());
ui->Depth->setValue(hole->Depth.getValue());
ui->Depth->blockSignals(false);
}
ui->Depth->setDisabled(ro);
}
else if (&Prop == &pcHole->DrillPoint) {
else if (&Prop == &hole->DrillPoint) {
ui->drillPointFlat->setEnabled(true);
ui->drillPointAngled->setEnabled(true);
std::string drillPoint(pcHole->DrillPoint.getValueAsString());
std::string drillPoint(hole->DrillPoint.getValueAsString());
if (drillPoint == "Flat" && !ui->drillPointFlat->isChecked()) {
ui->drillPointFlat->blockSignals(true);
ui->drillPointFlat->setChecked(true);
@@ -896,83 +906,83 @@ void TaskHoleParameters::changedObject(const App::Document&, const App::Property
ui->drillPointFlat->setDisabled(ro);
ui->drillPointAngled->setDisabled(ro);
}
else if (&Prop == &pcHole->DrillPointAngle) {
else if (&Prop == &hole->DrillPointAngle) {
ui->DrillPointAngle->setEnabled(true);
if (ui->DrillPointAngle->value().getValue() != pcHole->DrillPointAngle.getValue()) {
if (ui->DrillPointAngle->value().getValue() != hole->DrillPointAngle.getValue()) {
ui->DrillPointAngle->blockSignals(true);
ui->DrillPointAngle->setValue(pcHole->DrillPointAngle.getValue());
ui->DrillPointAngle->setValue(hole->DrillPointAngle.getValue());
ui->DrillPointAngle->blockSignals(false);
}
ui->DrillPointAngle->setDisabled(ro);
}
else if (&Prop == &pcHole->DrillForDepth) {
else if (&Prop == &hole->DrillForDepth) {
ui->DrillForDepth->setEnabled(true);
if (ui->DrillForDepth->isChecked() ^ pcHole->DrillForDepth.getValue()) {
if (ui->DrillForDepth->isChecked() ^ hole->DrillForDepth.getValue()) {
ui->DrillForDepth->blockSignals(true);
ui->DrillForDepth->setChecked(pcHole->DrillForDepth.getValue());
ui->DrillForDepth->setChecked(hole->DrillForDepth.getValue());
ui->DrillForDepth->blockSignals(false);
}
ui->DrillForDepth->setDisabled(ro);
}
else if (&Prop == &pcHole->Tapered) {
else if (&Prop == &hole->Tapered) {
ui->Tapered->setEnabled(true);
if (ui->Tapered->isChecked() ^ pcHole->Tapered.getValue()) {
if (ui->Tapered->isChecked() ^ hole->Tapered.getValue()) {
ui->Tapered->blockSignals(true);
ui->Tapered->setChecked(pcHole->Tapered.getValue());
ui->Tapered->setChecked(hole->Tapered.getValue());
ui->Tapered->blockSignals(false);
}
ui->Tapered->setDisabled(ro);
}
else if (&Prop == &pcHole->TaperedAngle) {
else if (&Prop == &hole->TaperedAngle) {
ui->TaperedAngle->setEnabled(true);
if (ui->TaperedAngle->value().getValue() != pcHole->TaperedAngle.getValue()) {
if (ui->TaperedAngle->value().getValue() != hole->TaperedAngle.getValue()) {
ui->TaperedAngle->blockSignals(true);
ui->TaperedAngle->setValue(pcHole->TaperedAngle.getValue());
ui->TaperedAngle->setValue(hole->TaperedAngle.getValue());
ui->TaperedAngle->blockSignals(false);
}
ui->TaperedAngle->setDisabled(ro);
}
else if (&Prop == &pcHole->ModelThread) {
else if (&Prop == &hole->ModelThread) {
ui->ModelThread->setEnabled(true);
if (ui->ModelThread->isChecked() ^ pcHole->ModelThread.getValue()) {
if (ui->ModelThread->isChecked() ^ hole->ModelThread.getValue()) {
ui->ModelThread->blockSignals(true);
ui->ModelThread->setChecked(pcHole->ModelThread.getValue());
ui->ModelThread->setChecked(hole->ModelThread.getValue());
ui->ModelThread->blockSignals(false);
}
ui->ModelThread->setDisabled(ro);
}
else if (&Prop == &pcHole->UseCustomThreadClearance) {
else if (&Prop == &hole->UseCustomThreadClearance) {
ui->UseCustomThreadClearance->setEnabled(true);
if (ui->UseCustomThreadClearance->isChecked() ^ pcHole->UseCustomThreadClearance.getValue()) {
if (ui->UseCustomThreadClearance->isChecked() ^ hole->UseCustomThreadClearance.getValue()) {
ui->UseCustomThreadClearance->blockSignals(true);
ui->UseCustomThreadClearance->setChecked(pcHole->UseCustomThreadClearance.getValue());
ui->UseCustomThreadClearance->setChecked(hole->UseCustomThreadClearance.getValue());
ui->UseCustomThreadClearance->blockSignals(false);
}
ui->UseCustomThreadClearance->setDisabled(ro);
}
else if (&Prop == &pcHole->CustomThreadClearance) {
else if (&Prop == &hole->CustomThreadClearance) {
ui->CustomThreadClearance->setEnabled(true);
if (ui->CustomThreadClearance->value().getValue() != pcHole->CustomThreadClearance.getValue()) {
if (ui->CustomThreadClearance->value().getValue() != hole->CustomThreadClearance.getValue()) {
ui->CustomThreadClearance->blockSignals(true);
ui->CustomThreadClearance->setValue(pcHole->CustomThreadClearance.getValue());
ui->CustomThreadClearance->setValue(hole->CustomThreadClearance.getValue());
ui->CustomThreadClearance->blockSignals(false);
}
ui->CustomThreadClearance->setDisabled(ro);
}
else if (&Prop == &pcHole->ThreadDepthType) {
else if (&Prop == &hole->ThreadDepthType) {
ui->ThreadDepthType->setEnabled(true);
if (ui->ThreadDepthType->currentIndex() != pcHole->ThreadDepthType.getValue()) {
if (ui->ThreadDepthType->currentIndex() != hole->ThreadDepthType.getValue()) {
ui->ThreadDepthType->blockSignals(true);
ui->ThreadDepthType->setCurrentIndex(pcHole->ThreadDepthType.getValue());
ui->ThreadDepthType->setCurrentIndex(hole->ThreadDepthType.getValue());
ui->ThreadDepthType->blockSignals(false);
}
ui->ThreadDepthType->setDisabled(ro);
}
else if (&Prop == &pcHole->ThreadDepth) {
else if (&Prop == &hole->ThreadDepth) {
ui->ThreadDepth->setEnabled(true);
if (ui->ThreadDepth->value().getValue() != pcHole->ThreadDepth.getValue()) {
if (ui->ThreadDepth->value().getValue() != hole->ThreadDepth.getValue()) {
ui->ThreadDepth->blockSignals(true);
ui->ThreadDepth->setValue(pcHole->ThreadDepth.getValue());
ui->ThreadDepth->setValue(hole->ThreadDepth.getValue());
ui->ThreadDepth->blockSignals(false);
}
ui->ThreadDepth->setDisabled(ro);
@@ -1125,8 +1135,7 @@ double TaskHoleParameters::getThreadDepth() const
void TaskHoleParameters::apply()
{
auto obj = vp->getObject();
PartDesign::Hole* pcHole = static_cast<PartDesign::Hole*>(vp->getObject());
auto hole = getObject<PartDesign::Hole>();
isApplying = true;
@@ -1138,40 +1147,40 @@ void TaskHoleParameters::apply()
ui->DrillPointAngle->apply();
ui->TaperedAngle->apply();
if (!pcHole->Threaded.isReadOnly())
FCMD_OBJ_CMD(obj, "Threaded = " << (getThreaded() ? 1 : 0));
if (!pcHole->ModelThread.isReadOnly())
FCMD_OBJ_CMD(obj, "ModelThread = " << (getModelThread() ? 1 : 0));
if (!pcHole->ThreadDepthType.isReadOnly())
FCMD_OBJ_CMD(obj, "ThreadDepthType = " << getThreadDepthType());
if (!pcHole->ThreadDepth.isReadOnly())
FCMD_OBJ_CMD(obj, "ThreadDepth = " << getThreadDepth());
if (!pcHole->UseCustomThreadClearance.isReadOnly())
FCMD_OBJ_CMD(obj, "UseCustomThreadClearance = " << (getUseCustomThreadClearance() ? 1 : 0));
if (!pcHole->CustomThreadClearance.isReadOnly())
FCMD_OBJ_CMD(obj, "CustomThreadClearance = " << getCustomThreadClearance());
if (!pcHole->ThreadType.isReadOnly())
FCMD_OBJ_CMD(obj, "ThreadType = " << getThreadType());
if (!pcHole->ThreadSize.isReadOnly())
FCMD_OBJ_CMD(obj, "ThreadSize = " << getThreadSize());
if (!pcHole->ThreadClass.isReadOnly())
FCMD_OBJ_CMD(obj, "ThreadClass = " << getThreadClass());
if (!pcHole->ThreadFit.isReadOnly())
FCMD_OBJ_CMD(obj, "ThreadFit = " << getThreadFit());
if (!pcHole->ThreadDirection.isReadOnly())
FCMD_OBJ_CMD(obj, "ThreadDirection = " << getThreadDirection());
if (!pcHole->HoleCutType.isReadOnly())
FCMD_OBJ_CMD(obj, "HoleCutType = " << getHoleCutType());
if (!pcHole->HoleCutCustomValues.isReadOnly())
FCMD_OBJ_CMD(obj, "HoleCutCustomValues = " << (getHoleCutCustomValues() ? 1 : 0));
if (!pcHole->DepthType.isReadOnly())
FCMD_OBJ_CMD(obj, "DepthType = " << getDepthType());
if (!pcHole->DrillPoint.isReadOnly())
FCMD_OBJ_CMD(obj, "DrillPoint = " << getDrillPoint());
if (!pcHole->DrillForDepth.isReadOnly())
FCMD_OBJ_CMD(obj, "DrillForDepth = " << (getDrillForDepth() ? 1 : 0));
if (!pcHole->Tapered.isReadOnly())
FCMD_OBJ_CMD(obj, "Tapered = " << getTapered());
if (!hole->Threaded.isReadOnly())
FCMD_OBJ_CMD(hole, "Threaded = " << (getThreaded() ? 1 : 0));
if (!hole->ModelThread.isReadOnly())
FCMD_OBJ_CMD(hole, "ModelThread = " << (getModelThread() ? 1 : 0));
if (!hole->ThreadDepthType.isReadOnly())
FCMD_OBJ_CMD(hole, "ThreadDepthType = " << getThreadDepthType());
if (!hole->ThreadDepth.isReadOnly())
FCMD_OBJ_CMD(hole, "ThreadDepth = " << getThreadDepth());
if (!hole->UseCustomThreadClearance.isReadOnly())
FCMD_OBJ_CMD(hole, "UseCustomThreadClearance = " << (getUseCustomThreadClearance() ? 1 : 0));
if (!hole->CustomThreadClearance.isReadOnly())
FCMD_OBJ_CMD(hole, "CustomThreadClearance = " << getCustomThreadClearance());
if (!hole->ThreadType.isReadOnly())
FCMD_OBJ_CMD(hole, "ThreadType = " << getThreadType());
if (!hole->ThreadSize.isReadOnly())
FCMD_OBJ_CMD(hole, "ThreadSize = " << getThreadSize());
if (!hole->ThreadClass.isReadOnly())
FCMD_OBJ_CMD(hole, "ThreadClass = " << getThreadClass());
if (!hole->ThreadFit.isReadOnly())
FCMD_OBJ_CMD(hole, "ThreadFit = " << getThreadFit());
if (!hole->ThreadDirection.isReadOnly())
FCMD_OBJ_CMD(hole, "ThreadDirection = " << getThreadDirection());
if (!hole->HoleCutType.isReadOnly())
FCMD_OBJ_CMD(hole, "HoleCutType = " << getHoleCutType());
if (!hole->HoleCutCustomValues.isReadOnly())
FCMD_OBJ_CMD(hole, "HoleCutCustomValues = " << (getHoleCutCustomValues() ? 1 : 0));
if (!hole->DepthType.isReadOnly())
FCMD_OBJ_CMD(hole, "DepthType = " << getDepthType());
if (!hole->DrillPoint.isReadOnly())
FCMD_OBJ_CMD(hole, "DrillPoint = " << getDrillPoint());
if (!hole->DrillForDepth.isReadOnly())
FCMD_OBJ_CMD(hole, "DrillForDepth = " << (getDrillForDepth() ? 1 : 0));
if (!hole->Tapered.isReadOnly())
FCMD_OBJ_CMD(hole, "Tapered = " << getTapered());
isApplying = false;
}

View File

@@ -128,8 +128,11 @@ void TaskLoftParameters::updateUI()
{
// we must assure the changed loft is kept visible on section changes,
// see https://forum.freecad.org/viewtopic.php?f=3&t=63252
PartDesign::Loft* loft = static_cast<PartDesign::Loft*>(vp->getObject());
vp->makeTemporaryVisible(!loft->Sections.getValues().empty());
auto loft = getObject<PartDesign::Loft>();
if (loft) {
auto view = getViewObject();
view->makeTemporaryVisible(!loft->Sections.getValues().empty());
}
}
void TaskLoftParameters::onSelectionChanged(const Gui::SelectionChanges& msg)
@@ -173,11 +176,11 @@ bool TaskLoftParameters::referenceSelected(const Gui::SelectionChanges& msg) con
if (msg.Type == Gui::SelectionChanges::AddSelection && selectionMode != none) {
if (strcmp(msg.pDocName, vp->getObject()->getDocument()->getName()) != 0)
if (strcmp(msg.pDocName, getObject()->getDocument()->getName()) != 0)
return false;
// not allowed to reference ourself
const char* fname = vp->getObject()->getNameInDocument();
const char* fname = getObject()->getNameInDocument();
if (strcmp(msg.pObjectName, fname) == 0)
return false;
@@ -185,11 +188,13 @@ bool TaskLoftParameters::referenceSelected(const Gui::SelectionChanges& msg) con
//supported, not individual edges of a part
//change the references
PartDesign::Loft* loft = static_cast<PartDesign::Loft*>(vp->getObject());
App::DocumentObject* obj = loft->getDocument()->getObject(msg.pObjectName);
auto loft = getObject<PartDesign::Loft>();
App::Document* doc = loft->getDocument();
App::DocumentObject* obj = doc->getObject(msg.pObjectName);
if (selectionMode == refProfile) {
static_cast<ViewProviderLoft*>(vp)->highlightReferences(ViewProviderLoft::Profile, false);
auto view = getViewObject<ViewProviderLoft>();
view->highlightReferences(ViewProviderLoft::Profile, false);
loft->Profile.setValue(obj, {msg.pSubName});
return true;
}
@@ -199,18 +204,18 @@ bool TaskLoftParameters::referenceSelected(const Gui::SelectionChanges& msg) con
std::vector<App::DocumentObject*>::iterator f = std::find(refs.begin(), refs.end(), obj);
if (selectionMode == refAdd) {
if (f == refs.end())
loft->Sections.addValue(obj, {msg.pSubName});
else
if (f != refs.end()) {
return false; // duplicate selection
}
loft->Sections.addValue(obj, {msg.pSubName});
}
else if (selectionMode == refRemove) {
if (f != refs.end())
// Removing just the object this way instead of `refs.erase` and
// `setValues(ref)` cleanly ensures subnames are preserved.
loft->Sections.removeValue(obj);
else
if (f == refs.end()) {
return false;
}
loft->Sections.removeValue(obj);
}
return true;
@@ -241,17 +246,16 @@ void TaskLoftParameters::onDeleteSection()
delete item;
// search inside the list of sections
PartDesign::Loft* loft = static_cast<PartDesign::Loft*>(vp->getObject());
std::vector<App::DocumentObject*> refs = loft->Sections.getValues();
App::DocumentObject* obj = loft->getDocument()->getObject(data.constData());
std::vector<App::DocumentObject*>::iterator f = std::find(refs.begin(), refs.end(), obj);
if (f != refs.end()) {
// Removing just the object this way instead of `refs.erase` and
// `setValues(ref)` cleanly ensures subnames are preserved.
loft->Sections.removeValue(obj);
if (auto loft = getObject<PartDesign::Loft>()) {
std::vector<App::DocumentObject*> refs = loft->Sections.getValues();
App::DocumentObject* obj = loft->getDocument()->getObject(data.constData());
std::vector<App::DocumentObject*>::iterator f = std::find(refs.begin(), refs.end(), obj);
if (f != refs.end()) {
loft->Sections.removeValue(obj);
recomputeFeature();
updateUI();
recomputeFeature();
updateUI();
}
}
}
}
@@ -259,31 +263,36 @@ void TaskLoftParameters::onDeleteSection()
void TaskLoftParameters::indexesMoved()
{
QAbstractItemModel* model = qobject_cast<QAbstractItemModel*>(sender());
if (!model)
if (!model) {
return;
PartDesign::Loft* loft = static_cast<PartDesign::Loft*>(vp->getObject());
auto originals = loft->Sections.getSubListValues();
int rows = model->rowCount();
for (int i = 0; i < rows; i++) {
QModelIndex index = model->index(i, 0);
originals[i] = index.data(Qt::UserRole).value<App::PropertyLinkSubList::SubSet>();
}
loft->Sections.setSubListValues(originals);
recomputeFeature();
updateUI();
if (auto loft = getObject<PartDesign::Loft>()) {
auto originals = loft->Sections.getSubListValues();
int rows = model->rowCount();
for (int i = 0; i < rows; i++) {
QModelIndex index = model->index(i, 0);
originals[i] = index.data(Qt::UserRole).value<App::PropertyLinkSubList::SubSet>();
}
loft->Sections.setSubListValues(originals);
recomputeFeature();
updateUI();
}
}
void TaskLoftParameters::clearButtons(const selectionModes notThis)
{
if (notThis != refProfile)
if (notThis != refProfile) {
ui->buttonProfileBase->setChecked(false);
if (notThis != refAdd)
}
if (notThis != refAdd) {
ui->buttonRefAdd->setChecked(false);
if (notThis != refRemove)
}
if (notThis != refRemove) {
ui->buttonRefRemove->setChecked(false);
}
}
void TaskLoftParameters::exitSelectionMode()
@@ -297,62 +306,52 @@ void TaskLoftParameters::changeEvent(QEvent * /*e*/)
{
}
void TaskLoftParameters::onClosed(bool val) {
static_cast<PartDesign::Loft*>(vp->getObject())->Closed.setValue(val);
recomputeFeature();
void TaskLoftParameters::onClosed(bool val)
{
if (auto loft = getObject<PartDesign::Loft>()) {
loft->Closed.setValue(val);
recomputeFeature();
}
}
void TaskLoftParameters::onRuled(bool val) {
static_cast<PartDesign::Loft*>(vp->getObject())->Ruled.setValue(val);
recomputeFeature();
void TaskLoftParameters::onRuled(bool val)
{
if (auto loft = getObject<PartDesign::Loft>()) {
loft->Ruled.setValue(val);
recomputeFeature();
}
}
void TaskLoftParameters::setSelectionMode(selectionModes mode, bool checked)
{
if (checked) {
clearButtons(mode);
Gui::Selection().clearSelection();
selectionMode = mode;
this->blockSelection(false);
}
else {
Gui::Selection().clearSelection();
selectionMode = none;
}
auto view = getViewObject<ViewProviderLoft>();
view->highlightReferences(ViewProviderLoft::Both, checked);
}
void TaskLoftParameters::onProfileButton(bool checked)
{
if (checked) {
clearButtons(refProfile);
Gui::Selection().clearSelection();
selectionMode = refProfile;
this->blockSelection(false);
static_cast<ViewProviderLoft*>(vp)->highlightReferences(ViewProviderLoft::Both, true);
}
else {
Gui::Selection().clearSelection();
selectionMode = none;
static_cast<ViewProviderLoft*>(vp)->highlightReferences(ViewProviderLoft::Both, false);
}
setSelectionMode(refProfile, checked);
}
void TaskLoftParameters::onRefButtonAdd(bool checked)
{
if (checked) {
clearButtons(refAdd);
Gui::Selection().clearSelection();
selectionMode = refAdd;
this->blockSelection(false);
static_cast<ViewProviderLoft*>(vp)->highlightReferences(ViewProviderLoft::Both, true);
}
else {
Gui::Selection().clearSelection();
selectionMode = none;
static_cast<ViewProviderLoft*>(vp)->highlightReferences(ViewProviderLoft::Both, false);
}
setSelectionMode(refAdd, checked);
}
void TaskLoftParameters::onRefButtonRemove(bool checked)
{
if (checked) {
clearButtons(refRemove);
Gui::Selection().clearSelection();
selectionMode = refRemove;
this->blockSelection(false);
static_cast<ViewProviderLoft*>(vp)->highlightReferences(ViewProviderLoft::Both, true);
}
else {
Gui::Selection().clearSelection();
selectionMode = none;
static_cast<ViewProviderLoft*>(vp)->highlightReferences(ViewProviderLoft::Both, false);
}
setSelectionMode(refRemove, checked);
}

View File

@@ -70,6 +70,7 @@ private:
void removeFromListWidget(QListWidget*w, QString name);
void clearButtons(const selectionModes notThis=none);
void exitSelectionMode();
void setSelectionMode(selectionModes mode, bool checked);
private:
QWidget* proxy;

View File

@@ -86,7 +86,7 @@ void TaskPadParameters::updateUI(int index)
void TaskPadParameters::onModeChanged(int index)
{
PartDesign::Pad* pcPad = static_cast<PartDesign::Pad*>(vp->getObject());
auto pcPad = getObject<PartDesign::Pad>();
switch (static_cast<Mode>(index)) {
case Mode::Dimension:

View File

@@ -142,13 +142,11 @@ TaskPipeParameters::TaskPipeParameters(ViewProviderPipe *PipeView, bool /*newObj
TaskPipeParameters::~TaskPipeParameters()
{
try {
if (vp) {
PartDesign::Pipe* pipe = static_cast<PartDesign::Pipe*>(vp->getObject());
if (auto pipe = getObject<PartDesign::Pipe>()) {
// setting visibility to true is needed when preselecting profile and path prior to invoking sweep
Gui::cmdGuiObject(pipe, "Visibility = True");
static_cast<ViewProviderPipe*>(vp)->highlightReferences(ViewProviderPipe::Spine, false);
static_cast<ViewProviderPipe*>(vp)->highlightReferences(ViewProviderPipe::Profile, false);
getViewObject<ViewProviderPipe>()->highlightReferences(ViewProviderPipe::Spine, false);
getViewObject<ViewProviderPipe>()->highlightReferences(ViewProviderPipe::Profile, false);
}
}
catch (const Standard_OutOfRange&) {
@@ -228,27 +226,32 @@ void TaskPipeParameters::onSelectionChanged(const Gui::SelectionChanges& msg)
void TaskPipeParameters::onTransitionChanged(int idx)
{
static_cast<PartDesign::Pipe*>(vp->getObject())->Transition.setValue(idx);
recomputeFeature();
if (auto pipe = getObject<PartDesign::Pipe>()) {
pipe->Transition.setValue(idx);
recomputeFeature();
}
}
void TaskPipeParameters::onProfileButton(bool checked)
{
if (checked) {
PartDesign::Pipe* pipe = static_cast<PartDesign::Pipe*>(vp->getObject());
Gui::Document* doc = vp->getDocument();
if (auto pipe = getObject<PartDesign::Pipe>()) {
Gui::Document* doc = getGuiDocument();
if (pipe->Profile.getValue()) {
auto* pvp = doc->getViewProvider(pipe->Profile.getValue());
pvp->setVisible(true);
if (pipe->Profile.getValue()) {
auto* pvp = doc->getViewProvider(pipe->Profile.getValue());
pvp->setVisible(true);
}
}
}
}
void TaskPipeParameters::onTangentChanged(bool checked)
{
static_cast<PartDesign::Pipe*>(vp->getObject())->SpineTangent.setValue(checked);
recomputeFeature();
if (auto pipe = getObject<PartDesign::Pipe>()) {
pipe->SpineTangent.setValue(checked);
recomputeFeature();
}
}
void TaskPipeParameters::removeFromListWidget(QListWidget* widget, QString itemstr)
@@ -272,7 +275,7 @@ void TaskPipeParameters::onDeleteEdge()
delete item;
// search inside the list of spines
PartDesign::Pipe* pipe = static_cast<PartDesign::Pipe*>(vp->getObject());
auto pipe = getObject<PartDesign::Pipe>();
std::vector<std::string> refs = pipe->Spine.getSubValues();
std::string obj = data.constData();
std::vector<std::string>::iterator f = std::find(refs.begin(), refs.end(), obj);
@@ -293,21 +296,21 @@ bool TaskPipeParameters::referenceSelected(const SelectionChanges& msg) const
if (msg.Type == Gui::SelectionChanges::AddSelection &&
selectionMode != StateHandlerTaskPipe::SelectionModes::none) {
if (strcmp(msg.pDocName, vp->getObject()->getDocument()->getName()) != 0)
if (strcmp(msg.pDocName, getAppDocument()->getName()) != 0)
return false;
// not allowed to reference ourself
const char* fname = vp->getObject()->getNameInDocument();
const char* fname = getObject()->getNameInDocument();
if (strcmp(msg.pObjectName, fname) == 0)
return false;
switch (selectionMode) {
case StateHandlerTaskPipe::SelectionModes::refProfile:
{
PartDesign::Pipe* pipe = static_cast<PartDesign::Pipe*>(vp->getObject());
Gui::Document* doc = vp->getDocument();
auto pipe = getObject<PartDesign::Pipe>();
Gui::Document* doc = getGuiDocument();
static_cast<ViewProviderPipe*>(vp)->highlightReferences(ViewProviderPipe::Profile, false);
getViewObject<ViewProviderPipe>()->highlightReferences(ViewProviderPipe::Profile, false);
bool success = true;
App::DocumentObject* profile = pipe->getDocument()->getObject(msg.pObjectName);
@@ -335,11 +338,12 @@ bool TaskPipeParameters::referenceSelected(const SelectionChanges& msg) const
{
//change the references
std::string subName(msg.pSubName);
std::vector<std::string> refs = static_cast<PartDesign::Pipe*>(vp->getObject())->Spine.getSubValues();
auto pipe = getObject<PartDesign::Pipe>();
std::vector<std::string> refs = pipe->Spine.getSubValues();
std::vector<std::string>::iterator f = std::find(refs.begin(), refs.end(), subName);
if (selectionMode == StateHandlerTaskPipe::SelectionModes::refSpine) {
static_cast<ViewProviderPipe*>(vp)->highlightReferences(ViewProviderPipe::Spine, false);
getViewObject<ViewProviderPipe>()->highlightReferences(ViewProviderPipe::Spine, false);
refs.clear();
}
else if (selectionMode == StateHandlerTaskPipe::SelectionModes::refSpineEdgeAdd) {
@@ -355,8 +359,7 @@ bool TaskPipeParameters::referenceSelected(const SelectionChanges& msg) const
return false;
}
static_cast<PartDesign::Pipe*>(vp->getObject())->Spine.setValue(
vp->getObject()->getDocument()->getObject(msg.pObjectName), refs);
pipe->Spine.setValue(getAppDocument()->getObject(msg.pObjectName), refs);
return true;
}
default:
@@ -384,9 +387,8 @@ void TaskPipeParameters::exitSelectionMode()
void TaskPipeParameters::setVisibilityOfSpineAndProfile()
{
if (vp) {
PartDesign::Pipe* pipe = static_cast<PartDesign::Pipe*>(vp->getObject());
Gui::Document* doc = vp->getDocument();
if (auto pipe = getObject<PartDesign::Pipe>()) {
Gui::Document* doc = getGuiDocument();
// set visibility to the state when the pipe was opened
for (auto obj : pipe->Sections.getValues()) {
@@ -416,8 +418,8 @@ 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);
auto pipe = getObject<PartDesign::Pipe>();
auto pcActiveBody = PartDesignGui::getBodyFor (pipe, false);
if (!pcActiveBody) {
QMessageBox::warning(this, tr("Input error"), tr("No active body"));
return false;
@@ -426,16 +428,16 @@ bool TaskPipeParameters::accept()
std::vector<App::DocumentObject*> copies;
bool extReference = false;
App::DocumentObject* spine = pcPipe->Spine.getValue();
App::DocumentObject* auxSpine = pcPipe->AuxillerySpine.getValue();
App::DocumentObject* spine = pipe->Spine.getValue();
App::DocumentObject* auxSpine = pipe->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());
std::vector<App::DocumentObject*> objs = pipe->getDocument()->findObjects(App::DocumentObject::getClassTypeId(), nullptr, ba.constData());
if (!objs.empty()) {
pcPipe->Spine.setValue(objs.front());
pipe->Spine.setValue(objs.front());
spine = objs.front();
}
}
@@ -447,7 +449,7 @@ bool TaskPipeParameters::accept()
extReference = true;
}
else {
for (App::DocumentObject* obj : pcPipe->Sections.getValues()) {
for (App::DocumentObject* obj : pipe->Sections.getValues()) {
if (!pcActiveBody->hasObject(obj) && !pcActiveBody->getOrigin()->hasObject(obj)) {
extReference = true;
break;
@@ -466,20 +468,20 @@ bool TaskPipeParameters::accept()
if (!dlg.radioXRef->isChecked()) {
if (!pcActiveBody->hasObject(spine) && !pcActiveBody->getOrigin()->hasObject(spine)) {
pcPipe->Spine.setValue(PartDesignGui::TaskFeaturePick::makeCopy(spine, "",
pipe->Spine.setValue(PartDesignGui::TaskFeaturePick::makeCopy(spine, "",
dlg.radioIndependent->isChecked()),
pcPipe->Spine.getSubValues());
copies.push_back(pcPipe->Spine.getValue());
pipe->Spine.getSubValues());
copies.push_back(pipe->Spine.getValue());
}
else if (!pcActiveBody->hasObject(auxSpine) && !pcActiveBody->getOrigin()->hasObject(auxSpine)){
pcPipe->AuxillerySpine.setValue(PartDesignGui::TaskFeaturePick::makeCopy(auxSpine, "",
pipe->AuxillerySpine.setValue(PartDesignGui::TaskFeaturePick::makeCopy(auxSpine, "",
dlg.radioIndependent->isChecked()),
pcPipe->AuxillerySpine.getSubValues());
copies.push_back(pcPipe->AuxillerySpine.getValue());
pipe->AuxillerySpine.getSubValues());
copies.push_back(pipe->AuxillerySpine.getValue());
}
std::vector<App::PropertyLinkSubList::SubSet> subSets;
for (auto &subSet : pcPipe->Sections.getSubListValues()) {
for (auto &subSet : pipe->Sections.getSubListValues()) {
if (!pcActiveBody->hasObject(subSet.first) &&
!pcActiveBody->getOrigin()->hasObject(subSet.first)) {
subSets.emplace_back(
@@ -493,22 +495,22 @@ bool TaskPipeParameters::accept()
}
}
pcPipe->Sections.setSubListValues(subSets);
pipe->Sections.setSubListValues(subSets);
}
}
try {
setVisibilityOfSpineAndProfile();
App::DocumentObject* spine = pcPipe->Spine.getValue();
std::vector<std::string> subNames = pcPipe->Spine.getSubValues();
App::DocumentObject* spine = pipe->Spine.getValue();
std::vector<std::string> subNames = pipe->Spine.getSubValues();
App::PropertyLinkT propT(spine, subNames);
Gui::cmdAppObjectArgs(pcPipe, "Spine = %s", propT.getPropertyPython());
Gui::cmdAppObjectArgs(pipe, "Spine = %s", propT.getPropertyPython());
Gui::cmdAppDocument(pcPipe, "recompute()");
if (!vp->getObject()->isValid())
throw Base::RuntimeError(vp->getObject()->getStatusString());
Gui::cmdGuiDocument(pcPipe, "resetEdit()");
Gui::cmdAppDocument(pipe, "recompute()");
if (!getObject()->isValid())
throw Base::RuntimeError(getObject()->getStatusString());
Gui::cmdGuiDocument(pipe, "resetEdit()");
Gui::Command::commitCommand();
//we need to add the copied features to the body after the command action, as otherwise FreeCAD crashes unexplainably
@@ -597,8 +599,8 @@ TaskPipeOrientation::TaskPipeOrientation(ViewProviderPipe* PipeView, bool /*newO
TaskPipeOrientation::~TaskPipeOrientation()
{
try {
if (vp) {
static_cast<ViewProviderPipe*>(vp)->highlightReferences(ViewProviderPipe::AuxiliarySpine, false);
if (auto view = getViewObject<ViewProviderPipe>()) {
view->highlightReferences(ViewProviderPipe::AuxiliarySpine, false);
}
}
catch (const Standard_OutOfRange&) {
@@ -607,8 +609,10 @@ TaskPipeOrientation::~TaskPipeOrientation()
void TaskPipeOrientation::onOrientationChanged(int idx)
{
static_cast<PartDesign::Pipe*>(vp->getObject())->Mode.setValue(idx);
recomputeFeature();
if (auto pipe = getObject<PartDesign::Pipe>()) {
pipe->Mode.setValue(idx);
recomputeFeature();
}
}
void TaskPipeOrientation::clearButtons()
@@ -620,34 +624,37 @@ void TaskPipeOrientation::clearButtons()
void TaskPipeOrientation::exitSelectionMode()
{
// commenting because this should be handled by buttonToggled signal
// selectionMode = none;
Gui::Selection().clearSelection();
}
void TaskPipeOrientation::onClearButton()
{
static_cast<ViewProviderPipe*>(vp)->highlightReferences(ViewProviderPipe::AuxiliarySpine, false);
ui->listWidgetReferences->clear();
ui->profileBaseEdit->clear();
static_cast<PartDesign::Pipe*>(vp->getObject())->AuxillerySpine.setValue(nullptr);
if (auto view = getViewObject<ViewProviderPipe>()) {
view->highlightReferences(ViewProviderPipe::AuxiliarySpine, false);
getObject<PartDesign::Pipe>()->AuxillerySpine.setValue(nullptr);
}
}
void TaskPipeOrientation::onCurvelinearChanged(bool checked)
{
static_cast<PartDesign::Pipe*>(vp->getObject())->AuxilleryCurvelinear.setValue(checked);
recomputeFeature();
if (auto pipe = getObject<PartDesign::Pipe>()) {
pipe->AuxilleryCurvelinear.setValue(checked);
recomputeFeature();
}
}
void TaskPipeOrientation::onBinormalChanged(double)
{
Base::Vector3d vec(ui->doubleSpinBoxX->value(),
ui->doubleSpinBoxY->value(),
ui->doubleSpinBoxZ->value());
if (auto pipe = getObject<PartDesign::Pipe>()) {
Base::Vector3d vec(ui->doubleSpinBoxX->value(),
ui->doubleSpinBoxY->value(),
ui->doubleSpinBoxZ->value());
static_cast<PartDesign::Pipe*>(vp->getObject())->Binormal.setValue(vec);
recomputeFeature();
pipe->Binormal.setValue(vec);
recomputeFeature();
}
}
void TaskPipeOrientation::onSelectionChanged(const SelectionChanges& msg)
@@ -675,8 +682,9 @@ void TaskPipeOrientation::onSelectionChanged(const SelectionChanges& msg)
}
else if (stateHandler->getSelectionMode() == StateHandlerTaskPipe::SelectionModes::refAuxSpineEdgeRemove) {
QString sub = QString::fromLatin1(msg.pSubName);
if (!sub.isEmpty())
if (!sub.isEmpty()) {
removeFromListWidget(ui->listWidgetReferences, sub);
}
else {
ui->profileBaseEdit->clear();
}
@@ -693,7 +701,8 @@ void TaskPipeOrientation::onSelectionChanged(const SelectionChanges& msg)
}
clearButtons();
static_cast<ViewProviderPipe*>(vp)->highlightReferences(ViewProviderPipe::AuxiliarySpine, false);
auto view = getViewObject<ViewProviderPipe>();
view->highlightReferences(ViewProviderPipe::AuxiliarySpine, false);
recomputeFeature();
}
@@ -710,38 +719,42 @@ bool TaskPipeOrientation::referenceSelected(const SelectionChanges& msg) const
(selectionMode == StateHandlerTaskPipe::SelectionModes::refAuxSpine ||
selectionMode == StateHandlerTaskPipe::SelectionModes::refAuxSpineEdgeAdd ||
selectionMode == StateHandlerTaskPipe::SelectionModes::refAuxSpineEdgeRemove)) {
if (strcmp(msg.pDocName, vp->getObject()->getDocument()->getName()) != 0)
if (strcmp(msg.pDocName, getObject()->getDocument()->getName()) != 0)
return false;
// not allowed to reference ourself
const char* fname = vp->getObject()->getNameInDocument();
const char* fname = getObject()->getNameInDocument();
if (strcmp(msg.pObjectName, fname) == 0)
return false;
//change the references
std::string subName(msg.pSubName);
std::vector<std::string> refs = static_cast<PartDesign::Pipe*>(vp->getObject())->AuxillerySpine.getSubValues();
std::vector<std::string>::iterator f = std::find(refs.begin(), refs.end(), subName);
if (auto pipe = getObject<PartDesign::Pipe>()) {
//change the references
std::string subName(msg.pSubName);
std::vector<std::string> refs = pipe->AuxillerySpine.getSubValues();
std::vector<std::string>::iterator f = std::find(refs.begin(), refs.end(), subName);
if (selectionMode == StateHandlerTaskPipe::SelectionModes::refAuxSpine) {
refs.clear();
}
else if (selectionMode == StateHandlerTaskPipe::SelectionModes::refAuxSpineEdgeAdd) {
if (f != refs.end()) {
return false; // duplicate selection
}
if (selectionMode == StateHandlerTaskPipe::SelectionModes::refAuxSpine) {
refs.clear();
}
else if (selectionMode == StateHandlerTaskPipe::SelectionModes::refAuxSpineEdgeAdd) {
if (f == refs.end())
refs.push_back(subName);
else
return false; // duplicate selection
}
else if (selectionMode == StateHandlerTaskPipe::SelectionModes::refAuxSpineEdgeRemove) {
if (f != refs.end())
refs.erase(f);
else
return false;
}
}
else if (selectionMode == StateHandlerTaskPipe::SelectionModes::refAuxSpineEdgeRemove) {
if (f == refs.end()) {
return false;
}
static_cast<PartDesign::Pipe*>(vp->getObject())->AuxillerySpine.setValue
(vp->getObject()->getDocument()->getObject(msg.pObjectName), refs);
return true;
refs.erase(f);
}
App::Document* doc = pipe->getDocument();
pipe->AuxillerySpine.setValue(doc->getObject(msg.pObjectName), refs);
return true;
}
}
return false;
@@ -768,17 +781,18 @@ void TaskPipeOrientation::onDeleteItem()
delete item;
// search inside the list of spines
PartDesign::Pipe* pipe = static_cast<PartDesign::Pipe*>(vp->getObject());
std::vector<std::string> refs = pipe->AuxillerySpine.getSubValues();
std::string obj = data.constData();
std::vector<std::string>::iterator f = std::find(refs.begin(), refs.end(), obj);
if (auto pipe = getObject<PartDesign::Pipe>()) {
std::vector<std::string> refs = pipe->AuxillerySpine.getSubValues();
std::string obj = data.constData();
std::vector<std::string>::iterator f = std::find(refs.begin(), refs.end(), obj);
// if something was found, delete it and update the spine list
if (f != refs.end()) {
refs.erase(f);
pipe->AuxillerySpine.setValue(pipe->AuxillerySpine.getValue(), refs);
clearButtons();
recomputeFeature();
// if something was found, delete it and update the spine list
if (f != refs.end()) {
refs.erase(f);
pipe->AuxillerySpine.setValue(pipe->AuxillerySpine.getValue(), refs);
clearButtons();
recomputeFeature();
}
}
}
}
@@ -852,8 +866,8 @@ TaskPipeScaling::TaskPipeScaling(ViewProviderPipe* PipeView, bool /*newObj*/, QW
TaskPipeScaling::~TaskPipeScaling()
{
try {
if (vp) {
static_cast<ViewProviderPipe*>(vp)->highlightReferences(ViewProviderPipe::Section, false);
if (auto view = getViewObject<ViewProviderPipe>()) {
view->highlightReferences(ViewProviderPipe::Section, false);
}
}
catch (const Standard_OutOfRange&) {
@@ -863,21 +877,22 @@ TaskPipeScaling::~TaskPipeScaling()
void TaskPipeScaling::indexesMoved()
{
QAbstractItemModel* model = qobject_cast<QAbstractItemModel*>(sender());
if (!model)
if (!model) {
return;
PartDesign::Pipe* pipe = static_cast<PartDesign::Pipe*>(vp->getObject());
auto originals = pipe->Sections.getSubListValues();
int rows = model->rowCount();
for (int i = 0; i < rows; i++) {
QModelIndex index = model->index(i, 0);
originals[i] = index.data(Qt::UserRole).value<App::PropertyLinkSubList::SubSet>();
}
pipe->Sections.setSubListValues(originals);
recomputeFeature();
updateUI(ui->stackedWidget->currentIndex());
if (auto pipe = getObject<PartDesign::Pipe>()) {
auto originals = pipe->Sections.getSubListValues();
int rows = model->rowCount();
for (int i = 0; i < rows; i++) {
QModelIndex index = model->index(i, 0);
originals[i] = index.data(Qt::UserRole).value<App::PropertyLinkSubList::SubSet>();
}
pipe->Sections.setSubListValues(originals);
recomputeFeature();
updateUI(ui->stackedWidget->currentIndex());
}
}
void TaskPipeScaling::clearButtons()
@@ -888,15 +903,15 @@ void TaskPipeScaling::clearButtons()
void TaskPipeScaling::exitSelectionMode()
{
// commenting because this should be handled by buttonToggled signal
// selectionMode = none;
Gui::Selection().clearSelection();
}
void TaskPipeScaling::onScalingChanged(int idx)
{
updateUI(idx);
static_cast<PartDesign::Pipe*>(vp->getObject())->Transformation.setValue(idx);
if (auto pipe = getObject<PartDesign::Pipe>()) {
updateUI(idx);
pipe->Transformation.setValue(idx);
}
}
void TaskPipeScaling::onSelectionChanged(const SelectionChanges& msg)
@@ -937,40 +952,39 @@ bool TaskPipeScaling::referenceSelected(const SelectionChanges& msg) const
if ((msg.Type == Gui::SelectionChanges::AddSelection) &&
((selectionMode == StateHandlerTaskPipe::SelectionModes::refSectionAdd) ||
(selectionMode == StateHandlerTaskPipe::SelectionModes::refSectionRemove))) {
if (strcmp(msg.pDocName, vp->getObject()->getDocument()->getName()) != 0)
if (strcmp(msg.pDocName, getObject()->getDocument()->getName()) != 0)
return false;
// not allowed to reference ourself
const char* fname = vp->getObject()->getNameInDocument();
const char* fname = getObject()->getNameInDocument();
if (strcmp(msg.pObjectName, fname) == 0)
return false;
//every selection needs to be a profile in itself, hence currently only full objects are
//supported, not individual edges of a part
//change the references
PartDesign::Pipe* pipe = static_cast<PartDesign::Pipe*>(vp->getObject());
std::vector<App::DocumentObject*> refs = pipe->Sections.getValues();
App::DocumentObject* obj = vp->getObject()->getDocument()->getObject(msg.pObjectName);
std::vector<App::DocumentObject*>::iterator f = std::find(refs.begin(), refs.end(), obj);
if (auto pipe = getObject<PartDesign::Pipe>()) {
std::vector<App::DocumentObject*> refs = pipe->Sections.getValues();
App::DocumentObject* obj = pipe->getDocument()->getObject(msg.pObjectName);
std::vector<App::DocumentObject*>::iterator f = std::find(refs.begin(), refs.end(), obj);
if (selectionMode == StateHandlerTaskPipe::SelectionModes::refSectionAdd) {
if (f != refs.end()) {
return false; // duplicate selection
}
if (selectionMode == StateHandlerTaskPipe::SelectionModes::refSectionAdd) {
if (f == refs.end())
pipe->Sections.addValue(obj, {msg.pSubName});
else
return false; // duplicate selection
}
else {
if (f != refs.end())
// Removing just the object this way instead of `refs.erase` and
// `setValues(ref)` cleanly ensures subnames are preserved.
pipe->Sections.removeValue(obj);
else
return false;
}
}
else {
if (f == refs.end()) {
return false;
}
static_cast<ViewProviderPipe*>(vp)->highlightReferences(ViewProviderPipe::Section, false);
return true;
pipe->Sections.removeValue(obj);
}
auto view = getViewObject<ViewProviderPipe>();
view->highlightReferences(ViewProviderPipe::Section, false);
return true;
}
}
return false;
@@ -996,19 +1010,16 @@ void TaskPipeScaling::onDeleteSection()
QByteArray data(item->data(Qt::UserRole).value<App::PropertyLinkSubList::SubSet>().first->getNameInDocument());
delete item;
// search inside the list of sections
PartDesign::Pipe* pipe = static_cast<PartDesign::Pipe*>(vp->getObject());
std::vector<App::DocumentObject*> refs = pipe->Sections.getValues();
App::DocumentObject* obj = pipe->getDocument()->getObject(data.constData());
std::vector<App::DocumentObject*>::iterator f = std::find(refs.begin(), refs.end(), obj);
if (auto pipe = getObject<PartDesign::Pipe>()) {
std::vector<App::DocumentObject*> refs = pipe->Sections.getValues();
App::DocumentObject* obj = pipe->getDocument()->getObject(data.constData());
std::vector<App::DocumentObject*>::iterator f = std::find(refs.begin(), refs.end(), obj);
// if something was found, delete it and update the section list
if (f != refs.end()) {
// Removing just the object this way instead of `refs.erase` and
// `setValues(ref)` cleanly ensures subnames are preserved.
pipe->Sections.removeValue(obj);
clearButtons();
recomputeFeature();
if (f != refs.end()) {
pipe->Sections.removeValue(obj);
clearButtons();
recomputeFeature();
}
}
}
}

View File

@@ -101,9 +101,6 @@ private:
void exitSelectionMode();
void setVisibilityOfSpineAndProfile();
ViewProviderPipe* getPipeView() const
{ return static_cast<ViewProviderPipe*>(vp); }
bool spineShow = false;
bool profileShow = false;
bool auxSpineShow = false;

View File

@@ -87,7 +87,7 @@ void TaskPocketParameters::updateUI(int index)
void TaskPocketParameters::onModeChanged(int index)
{
PartDesign::Pocket* pcPocket = static_cast<PartDesign::Pocket*>(vp->getObject());
auto pcPocket = getObject<PartDesign::Pocket>();
switch (static_cast<Mode>(index)) {
case Mode::Dimension:

View File

@@ -59,7 +59,7 @@ TaskRevolutionParameters::TaskRevolutionParameters(PartDesignGui::ViewProvider*
this->groupLayout()->addWidget(proxy);
// bind property mirrors
if (auto *rev = dynamic_cast<PartDesign::Revolution *>(vp->getObject())) {
if (auto rev = getObject<PartDesign::Revolution>()) {
this->propAngle = &(rev->Angle);
this->propAngle2 = &(rev->Angle2);
this->propMidPlane = &(rev->Midplane);
@@ -69,7 +69,7 @@ TaskRevolutionParameters::TaskRevolutionParameters(PartDesignGui::ViewProvider*
ui->revolveAngle->bind(rev->Angle);
ui->revolveAngle2->bind(rev->Angle2);
}
else if (auto *rev = dynamic_cast<PartDesign::Groove *>(vp->getObject())) {
else if (auto rev = getObject<PartDesign::Groove>()) {
isGroove = true;
this->propAngle = &(rev->Angle);
this->propAngle2 = &(rev->Angle2);
@@ -93,7 +93,7 @@ TaskRevolutionParameters::TaskRevolutionParameters(PartDesignGui::ViewProvider*
setFocus();
// show the parts coordinate system axis for selection
PartDesign::Body * body = PartDesign::Body::findBodyOf ( vp->getObject () );
PartDesign::Body * body = PartDesign::Body::findBodyOf(getObject());
if (body) {
try {
App::Origin *origin = body->getOrigin();
@@ -148,7 +148,7 @@ void TaskRevolutionParameters::setupDialog()
// TODO: This should also be implemented for groove
if (!isGroove) {
PartDesign::Revolution* rev = static_cast<PartDesign::Revolution*>(vp->getObject());
auto rev = getObject<PartDesign::Revolution>();
ui->revolveAngle2->setValue(propAngle2->getValue());
ui->revolveAngle2->setMaximum(propAngle2->getMaximum());
ui->revolveAngle2->setMinimum(propAngle2->getMinimum());
@@ -156,7 +156,7 @@ void TaskRevolutionParameters::setupDialog()
index = rev->Type.getValue();
}
else {
PartDesign::Groove* rev = static_cast<PartDesign::Groove*>(vp->getObject());
auto rev = getObject<PartDesign::Groove>();
ui->revolveAngle2->setValue(propAngle2->getValue());
ui->revolveAngle2->setMaximum(propAngle2->getMaximum());
ui->revolveAngle2->setMinimum(propAngle2->getMinimum());
@@ -194,9 +194,10 @@ void TaskRevolutionParameters::fillAxisCombo(bool forceRefill)
ui->axis->clear();
axesInList.clear();
auto *pcFeat = dynamic_cast<PartDesign::ProfileBased*>(vp->getObject());
if (!pcFeat)
auto *pcFeat = getObject<PartDesign::ProfileBased>();
if (!pcFeat) {
throw Base::TypeError("The object is not ProfileBased.");
}
//add sketch axes
if (auto *pcSketch = dynamic_cast<Part::Part2DObject*>(pcFeat->Profile.getValue())) {
@@ -377,7 +378,7 @@ void TaskRevolutionParameters::onSelectionChanged(const Gui::SelectionChanges& m
exitSelectionMode();
std::vector<std::string> axis;
App::DocumentObject* selObj;
if (getReferencedSelection(vp->getObject(), msg, selObj, axis) && selObj) {
if (getReferencedSelection(getObject(), msg, selObj, axis) && selObj) {
propReferenceAxis->setValue(selObj, axis);
recomputeFeature();
@@ -470,24 +471,29 @@ void TaskRevolutionParameters::clearFaceName()
void TaskRevolutionParameters::onAngleChanged(double len)
{
propAngle->setValue(len);
exitSelectionMode();
recomputeFeature();
if (getObject()) {
propAngle->setValue(len);
exitSelectionMode();
recomputeFeature();
}
}
void TaskRevolutionParameters::onAngle2Changed(double len)
{
if (propAngle2)
propAngle2->setValue(len);
exitSelectionMode();
recomputeFeature();
if (getObject()) {
if (propAngle2) {
propAngle2->setValue(len);
}
exitSelectionMode();
recomputeFeature();
}
}
void TaskRevolutionParameters::onAxisChanged(int num)
{
if (isUpdateBlocked())
return;
PartDesign::ProfileBased* pcRevolution = static_cast<PartDesign::ProfileBased*>(vp->getObject());
auto pcRevolution = getObject<PartDesign::ProfileBased>();
if (axesInList.empty())
return;
@@ -549,30 +555,31 @@ void TaskRevolutionParameters::onAxisChanged(int num)
void TaskRevolutionParameters::onMidplane(bool on)
{
propMidPlane->setValue(on);
recomputeFeature();
if (getObject()) {
propMidPlane->setValue(on);
recomputeFeature();
}
}
void TaskRevolutionParameters::onReversed(bool on)
{
propReversed->setValue(on);
recomputeFeature();
if (getObject()) {
propReversed->setValue(on);
recomputeFeature();
}
}
void TaskRevolutionParameters::onModeChanged(int index)
{
App::PropertyEnumeration* pcType;
App::PropertyEnumeration* pcType {};
if (!isGroove)
pcType = &(static_cast<PartDesign::Revolution*>(vp->getObject())->Type);
pcType = &(getObject<PartDesign::Revolution>()->Type);
else
pcType = &(static_cast<PartDesign::Groove*>(vp->getObject())->Type);
pcType = &(getObject<PartDesign::Groove>()->Type);
switch (static_cast<PartDesign::Revolution::RevolMethod>(index)) {
case PartDesign::Revolution::RevolMethod::Dimension:
pcType->setValue("Angle");
// Avoid error message
// if (ui->revolveAngle->value() < Base::Quantity(Precision::Angular(), Base::Unit::Angle)) // TODO: Ensure radians/degree consistency
// ui->revolveAngle->setValue(5.0);
break;
case PartDesign::Revolution::RevolMethod::ToLast:
if (!isGroove)
@@ -597,16 +604,18 @@ void TaskRevolutionParameters::onModeChanged(int index)
void TaskRevolutionParameters::getReferenceAxis(App::DocumentObject*& obj, std::vector<std::string>& sub) const
{
if (axesInList.empty())
if (axesInList.empty()) {
throw Base::RuntimeError("Not initialized!");
}
int num = ui->axis->currentIndex();
const App::PropertyLinkSub &lnk = *(axesInList[num]);
if (!lnk.getValue()) {
throw Base::RuntimeError("Still in reference selection mode; reference wasn't selected yet");
} else {
PartDesign::ProfileBased* pcRevolution = static_cast<PartDesign::ProfileBased*>(vp->getObject());
if (!pcRevolution->getDocument()->isIn(lnk.getValue())){
}
else {
auto revolution = getObject<PartDesign::ProfileBased>();
if (!revolution->getDocument()->isIn(lnk.getValue())){
throw Base::RuntimeError("Object was deleted");
}
@@ -629,14 +638,16 @@ TaskRevolutionParameters::~TaskRevolutionParameters()
{
try {
//hide the parts coordinate system axis for selection
PartDesign::Body * body = vp ? PartDesign::Body::findBodyOf(vp->getObject()) : nullptr;
auto obj = getObject();
PartDesign::Body * body = obj ? PartDesign::Body::findBodyOf(obj) : nullptr;
if (body) {
App::Origin *origin = body->getOrigin();
ViewProviderOrigin* vpOrigin;
vpOrigin = static_cast<ViewProviderOrigin*>(Gui::Application::Instance->getViewProvider(origin));
vpOrigin->resetTemporaryVisibility();
}
} catch (const Base::Exception &ex) {
}
catch (const Base::Exception &ex) {
ex.ReportException();
}
@@ -663,7 +674,7 @@ void TaskRevolutionParameters::apply()
App::DocumentObject* obj;
getReferenceAxis(obj, sub);
std::string axis = buildLinkSingleSubPythonStr(obj, sub);
auto tobj = vp->getObject();
auto tobj = getObject();
FCMD_OBJ_CMD(tobj, "ReferenceAxis = " << axis);
FCMD_OBJ_CMD(tobj, "Midplane = " << (getMidplane() ? 1 : 0));
FCMD_OBJ_CMD(tobj, "Reversed = " << (getReversed() ? 1 : 0));

View File

@@ -61,10 +61,12 @@ TaskSketchBasedParameters::TaskSketchBasedParameters(PartDesignGui::ViewProvider
const QString TaskSketchBasedParameters::onAddSelection(const Gui::SelectionChanges& msg)
{
// Note: The validity checking has already been done in ReferenceSelection.cpp
PartDesign::ProfileBased* pcSketchBased = static_cast<PartDesign::ProfileBased*>(vp->getObject());
App::DocumentObject* selObj = pcSketchBased->getDocument()->getObject(msg.pObjectName);
if (selObj == pcSketchBased)
auto sketchBased = getObject<PartDesign::ProfileBased>();
App::DocumentObject* selObj = sketchBased->getDocument()->getObject(msg.pObjectName);
if (selObj == sketchBased) {
return QString();
}
std::string subname = msg.pSubName;
QString refStr;
@@ -72,54 +74,57 @@ const QString TaskSketchBasedParameters::onAddSelection(const Gui::SelectionChan
if (PartDesign::Feature::isDatum(selObj)) {
subname = "";
refStr = QString::fromLatin1(selObj->getNameInDocument());
} else if (subname.size() > 4) {
}
else if (subname.size() > 4) {
int faceId = std::atoi(&subname[4]);
refStr = QString::fromLatin1(selObj->getNameInDocument()) + QString::fromLatin1(":") + QObject::tr("Face") + QString::number(faceId);
}
std::vector<std::string> upToFaces(1,subname);
pcSketchBased->UpToFace.setValue(selObj, upToFaces);
sketchBased->UpToFace.setValue(selObj, upToFaces);
recomputeFeature();
return refStr;
}
void TaskSketchBasedParameters::startReferenceSelection(App::DocumentObject* profile, App::DocumentObject* base)
void TaskSketchBasedParameters::startReferenceSelection(App::DocumentObject* profile,
App::DocumentObject* base)
{
Gui::Document* doc = vp->getDocument();
if (doc) {
if (Gui::Document* doc = getGuiDocument()) {
doc->setHide(profile->getNameInDocument());
if (base)
if (base) {
doc->setShow(base->getNameInDocument());
}
}
}
void TaskSketchBasedParameters::finishReferenceSelection(App::DocumentObject* profile, App::DocumentObject* base)
void TaskSketchBasedParameters::finishReferenceSelection(App::DocumentObject* profile,
App::DocumentObject* base)
{
Gui::Document* doc = vp->getDocument();
if (doc) {
if (Gui::Document* doc = getGuiDocument()) {
doc->setShow(profile->getNameInDocument());
if (base)
if (base) {
doc->setHide(base->getNameInDocument());
}
}
}
void TaskSketchBasedParameters::onSelectReference(AllowSelectionFlags allow) {
void TaskSketchBasedParameters::onSelectReference(AllowSelectionFlags allow)
{
// Note: Even if there is no solid, App::Plane and Part::Datum can still be selected
PartDesign::ProfileBased* pcSketchBased = dynamic_cast<PartDesign::ProfileBased*>(vp->getObject());
if (pcSketchBased) {
if (auto sketchBased = getObject<PartDesign::ProfileBased>()) {
// The solid this feature will be fused to
App::DocumentObject* prevSolid = pcSketchBased->getBaseObject( /* silent =*/ true );
App::DocumentObject* prevSolid = sketchBased->getBaseObject( /* silent =*/ true );
if (AllowSelectionFlags::Int(allow) != int(AllowSelection::NONE)) {
startReferenceSelection(pcSketchBased, prevSolid);
startReferenceSelection(sketchBased, prevSolid);
this->blockSelection(false);
Gui::Selection().clearSelection();
Gui::Selection().addSelectionGate(new ReferenceSelection(prevSolid, allow));
}
else {
Gui::Selection().rmvSelectionGate();
finishReferenceSelection(pcSketchBased, prevSolid);
finishReferenceSelection(sketchBased, prevSolid);
this->blockSelection(true);
}
}
@@ -137,51 +142,63 @@ QVariant TaskSketchBasedParameters::setUpToFace(const QString& text)
return {};
QStringList parts = text.split(QChar::fromLatin1(':'));
if (parts.length() < 2)
parts.push_back(QString::fromLatin1(""));
if (parts.length() < 2) {
parts.push_back(QString());
}
// Check whether this is the name of an App::Plane or Part::Datum feature
App::DocumentObject* obj = vp->getObject()->getDocument()->getObject(parts[0].toLatin1());
if (!obj)
return {};
if (obj->isDerivedFrom<App::Plane>()) {
// everything is OK (we assume a Part can only have exactly 3 App::Plane objects located at the base of the feature tree)
App::Document* doc = getAppDocument();
if (!doc) {
return {};
}
else if (obj->isDerivedFrom<Part::Datum>()) {
App::DocumentObject* obj = doc->getObject(parts[0].toLatin1());
if (!obj) {
return {};
}
if (obj->isDerivedFrom<App::Plane>()) {
// everything is OK (we assume a Part can only have exactly 3 App::Plane objects
// located at the base of the feature tree)
return {};
}
if (obj->isDerivedFrom<Part::Datum>()) {
// it's up to the document to check that the datum plane is in the same body
return {};
}
else {
// We must expect that "parts[1]" is the translation of "Face" followed by an ID.
QString name;
QTextStream str(&name);
str << "^" << tr("Face") << "(\\d+)$";
QRegularExpression rx(name);
QRegularExpressionMatch match;
if (parts[1].indexOf(rx, 0, &match) < 0) {
return {};
}
int faceId = match.captured(1).toInt();
std::stringstream ss;
ss << "Face" << faceId;
std::vector<std::string> upToFaces(1, ss.str());
PartDesign::ProfileBased* pcSketchBased = static_cast<PartDesign::ProfileBased*>(vp->getObject());
pcSketchBased->UpToFace.setValue(obj, upToFaces);
recomputeFeature();
return QByteArray(ss.str().c_str());
// We must expect that "parts[1]" is the translation of "Face" followed by an ID.
QString name;
QTextStream str(&name);
str << "^" << tr("Face") << "(\\d+)$";
QRegularExpression rx(name);
QRegularExpressionMatch match;
if (parts[1].indexOf(rx, 0, &match) < 0) {
return {};
}
int faceId = match.captured(1).toInt();
std::stringstream ss;
ss << "Face" << faceId;
std::vector<std::string> upToFaces(1, ss.str());
auto sketchBased = getObject<PartDesign::ProfileBased>();
sketchBased->UpToFace.setValue(obj, upToFaces);
recomputeFeature();
return QByteArray(ss.str().c_str());
}
QVariant TaskSketchBasedParameters::objectNameByLabel(const QString& label,
const QVariant& suggest) const
{
// search for an object with the given label
App::Document* doc = this->vp->getObject()->getDocument();
App::Document* doc = getAppDocument();
if (!doc) {
return {};
}
// for faster access try the suggestion
if (suggest.isValid()) {
App::DocumentObject* obj = doc->getObject(suggest.toByteArray());
@@ -204,11 +221,15 @@ QVariant TaskSketchBasedParameters::objectNameByLabel(const QString& label,
QString TaskSketchBasedParameters::getFaceReference(const QString& obj, const QString& sub) const
{
App::Document* doc = this->vp->getObject()->getDocument();
QString o = obj.left(obj.indexOf(QString::fromLatin1(":")));
if (o.isEmpty())
App::Document* doc = getAppDocument();
if (!doc) {
return {};
}
QString o = obj.left(obj.indexOf(QString::fromLatin1(":")));
if (o.isEmpty()) {
return {};
}
return QString::fromLatin1(R"((App.getDocument("%1").%2, ["%3"]))")
.arg(QString::fromLatin1(doc->getName()), o, sub);