From 4524103dbcfc0599007917223febe6eb52e9369c Mon Sep 17 00:00:00 2001 From: jrheinlaender Date: Wed, 15 May 2013 20:37:14 +0430 Subject: [PATCH] Allow datum lines and planes for Transformed features' references --- .../PartDesign/App/FeatureLinearPattern.cpp | 28 +- src/Mod/PartDesign/App/FeatureMirrored.cpp | 33 +- .../PartDesign/App/FeaturePolarPattern.cpp | 17 +- .../Gui/TaskLinearPatternParameters.cpp | 142 ++--- .../Gui/TaskLinearPatternParameters.cpp.orig | 511 ++++++++++++++++++ .../Gui/TaskLinearPatternParameters.h | 2 +- .../Gui/TaskLinearPatternParameters.ui | 17 +- .../PartDesign/Gui/TaskMirroredParameters.cpp | 165 +++--- .../Gui/TaskMirroredParameters.cpp.orig | 412 ++++++++++++++ .../PartDesign/Gui/TaskMirroredParameters.h | 2 +- .../PartDesign/Gui/TaskMirroredParameters.ui | 17 +- .../Gui/TaskPolarPatternParameters.cpp | 86 ++- .../Gui/TaskPolarPatternParameters.cpp.orig | 424 +++++++++++++++ .../Gui/TaskPolarPatternParameters.h | 3 +- .../Gui/TaskTransformedParameters.cpp | 42 +- .../Gui/TaskTransformedParameters.h | 11 +- 16 files changed, 1709 insertions(+), 203 deletions(-) create mode 100644 src/Mod/PartDesign/Gui/TaskLinearPatternParameters.cpp.orig create mode 100644 src/Mod/PartDesign/Gui/TaskMirroredParameters.cpp.orig create mode 100644 src/Mod/PartDesign/Gui/TaskPolarPatternParameters.cpp.orig diff --git a/src/Mod/PartDesign/App/FeatureLinearPattern.cpp b/src/Mod/PartDesign/App/FeatureLinearPattern.cpp index 9841c4ccc0..f17846be44 100644 --- a/src/Mod/PartDesign/App/FeatureLinearPattern.cpp +++ b/src/Mod/PartDesign/App/FeatureLinearPattern.cpp @@ -34,6 +34,9 @@ #include "FeatureLinearPattern.h" +#include "DatumPlane.h" +#include "DatumLine.h" +#include #include #include #include @@ -79,10 +82,9 @@ const std::list LinearPattern::getTransformations(const std::vectorgetTypeId().isDerivedFrom(Part::Feature::getClassTypeId())) - throw Base::Exception("Direction reference must be edge or face of a feature"); + std::vector subStrings = Direction.getSubValues(); - if (subStrings.empty() || subStrings[0].empty()) + if (subStrings.empty()) throw Base::Exception("No direction reference specified"); gp_Dir dir; @@ -102,7 +104,23 @@ const std::list LinearPattern::getTransformations(const std::vectorPlacement.getValue(); dir = gp_Dir(axis.getDirection().x, axis.getDirection().y, axis.getDirection().z); - } else { + } else if (refObject->getTypeId().isDerivedFrom(PartDesign::Plane::getClassTypeId())) { + PartDesign::Plane* plane = static_cast(refObject); + Base::Vector3d d = plane->getNormal(); + dir = gp_Dir(d.x, d.y, d.z); + } else if (refObject->getTypeId().isDerivedFrom(PartDesign::Line::getClassTypeId())) { + PartDesign::Line* line = static_cast(refObject); + Base::Vector3d d = line->getDirection(); + dir = gp_Dir(d.x, d.y, d.z); + } else if (refObject->getTypeId().isDerivedFrom(App::Plane::getClassTypeId())) { + App::Plane* plane = static_cast(refObject); + Base::Rotation rot = plane->Placement.getValue().getRotation(); + Base::Vector3d d(0,0,1); + rot.multVec(d, d); + dir = gp_Dir(d.x, d.y, d.z); + } else if (refObject->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())) { + if (subStrings[0].empty()) + throw Base::Exception("No direction reference specified"); Part::Feature* refFeature = static_cast(refObject); Part::TopoShape refShape = refFeature->Shape.getShape(); TopoDS_Shape ref = refShape.getSubShape(subStrings[0].c_str()); @@ -128,6 +146,8 @@ const std::list LinearPattern::getTransformations(const std::vectorgetLocation().Inverted(); dir.Transform(invObjLoc.Transformation()); diff --git a/src/Mod/PartDesign/App/FeatureMirrored.cpp b/src/Mod/PartDesign/App/FeatureMirrored.cpp index 0206134bf7..a599a4eccb 100644 --- a/src/Mod/PartDesign/App/FeatureMirrored.cpp +++ b/src/Mod/PartDesign/App/FeatureMirrored.cpp @@ -31,8 +31,10 @@ #endif +#include #include #include "FeatureMirrored.h" +#include "DatumPlane.h" #include #include @@ -60,10 +62,8 @@ const std::list Mirrored::getTransformations(const std::vectorgetTypeId().isDerivedFrom(Part::Feature::getClassTypeId())) - throw Base::Exception("Mirror plane reference must be face of a feature"); std::vector subStrings = MirrorPlane.getSubValues(); - if (subStrings.empty() || subStrings[0].empty()) + if (subStrings.empty()) throw Base::Exception("No mirror plane reference specified"); gp_Pnt axbase; @@ -86,13 +86,29 @@ const std::list Mirrored::getTransformations(const std::vectorPlacement.getValue(); - axbase = gp_Pnt(axis.getBase().x, axis.getBase().y, axis.getBase().z); + axbase = gp_Pnt(axis.getBase().x, axis.getBase().y, axis.getBase().z); axdir = gp_Dir(axis.getDirection().x, axis.getDirection().y, axis.getDirection().z); - } else { + } else if (refObject->getTypeId().isDerivedFrom(PartDesign::Plane::getClassTypeId())) { + PartDesign::Plane* plane = static_cast(refObject); + Base::Vector3d base = plane->getBasePoint(); + axbase = gp_Pnt(base.x, base.y, base.z); + Base::Vector3d dir = plane->getNormal(); + axdir = gp_Dir(dir.x, dir.y, dir.z); + } else if (refObject->getTypeId().isDerivedFrom(App::Plane::getClassTypeId())) { + App::Plane* plane = static_cast(refObject); + Base::Vector3d base = plane->Placement.getValue().getPosition(); + axbase = gp_Pnt(base.x, base.y, base.z); + Base::Rotation rot = plane->Placement.getValue().getRotation(); + Base::Vector3d dir(0,0,1); + rot.multVec(dir, dir); + axdir = gp_Dir(dir.x, dir.y, dir.z); + } else if (refObject->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())) { + if (subStrings[0].empty()) + throw Base::Exception("No direction reference specified"); Part::TopoShape baseShape = static_cast(refObject)->Shape.getShape(); // TODO: Check for multiple mirror planes? - - TopoDS_Face face = TopoDS::Face(baseShape.getSubShape(subStrings[0].c_str())); + TopoDS_Shape shape = baseShape.getSubShape(subStrings[0].c_str()); + TopoDS_Face face = TopoDS::Face(shape); if (face.IsNull()) throw Base::Exception("Failed to extract mirror plane"); BRepAdaptor_Surface adapt(face); @@ -101,7 +117,10 @@ const std::list Mirrored::getTransformations(const std::vectorgetLocation().Inverted(); axbase.Transform(invObjLoc.Transformation()); axdir.Transform(invObjLoc.Transformation()); diff --git a/src/Mod/PartDesign/App/FeaturePolarPattern.cpp b/src/Mod/PartDesign/App/FeaturePolarPattern.cpp index e0906a29b0..653718d6a8 100644 --- a/src/Mod/PartDesign/App/FeaturePolarPattern.cpp +++ b/src/Mod/PartDesign/App/FeaturePolarPattern.cpp @@ -32,6 +32,7 @@ #include "FeaturePolarPattern.h" +#include "DatumLine.h" #include #include #include @@ -82,10 +83,8 @@ const std::list PolarPattern::getTransformations(const std::vectorgetTypeId().isDerivedFrom(Part::Feature::getClassTypeId())) - throw Base::Exception("Axis reference must be edge of a feature"); std::vector subStrings = Axis.getSubValues(); - if (subStrings.empty() || subStrings[0].empty()) + if (subStrings.empty()) throw Base::Exception("No axis reference specified"); gp_Pnt axbase; @@ -107,7 +106,15 @@ const std::list PolarPattern::getTransformations(const std::vectorPlacement.getValue(); axbase = gp_Pnt(axis.getBase().x, axis.getBase().y, axis.getBase().z); axdir = gp_Dir(axis.getDirection().x, axis.getDirection().y, axis.getDirection().z); - } else { + } else if (refObject->getTypeId().isDerivedFrom(PartDesign::Line::getClassTypeId())) { + PartDesign::Line* line = static_cast(refObject); + Base::Vector3d base = line->getBasePoint(); + axbase = gp_Pnt(base.x, base.y, base.z); + Base::Vector3d dir = line->getDirection(); + axdir = gp_Dir(dir.x, dir.y, dir.z); + } else if (refObject->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())) { + if (subStrings[0].empty()) + throw Base::Exception("No axis reference specified"); Part::Feature* refFeature = static_cast(refObject); Part::TopoShape refShape = refFeature->Shape.getShape(); TopoDS_Shape ref = refShape.getSubShape(subStrings[0].c_str()); @@ -125,6 +132,8 @@ const std::list PolarPattern::getTransformations(const std::vectorgetLocation().Inverted(); axbase.Transform(invObjLoc.Transformation()); diff --git a/src/Mod/PartDesign/Gui/TaskLinearPatternParameters.cpp b/src/Mod/PartDesign/Gui/TaskLinearPatternParameters.cpp index 621a10cf4b..c84f865597 100644 --- a/src/Mod/PartDesign/Gui/TaskLinearPatternParameters.cpp +++ b/src/Mod/PartDesign/Gui/TaskLinearPatternParameters.cpp @@ -31,6 +31,7 @@ #include "ui_TaskLinearPatternParameters.h" #include "TaskLinearPatternParameters.h" #include "TaskMultiTransformParameters.h" +#include "Workbench.h" #include #include #include @@ -43,6 +44,8 @@ #include #include #include +#include +#include #include using namespace PartDesignGui; @@ -155,15 +158,16 @@ void TaskLinearPatternParameters::updateUI() double length = pcLinearPattern->Length.getValue(); unsigned occurrences = pcLinearPattern->Occurrences.getValue(); + // Add user-defined sketch axes to the reference selection combo box App::DocumentObject* sketch = getSketchObject(); - int maxcount=2; + int maxcount=5; if (sketch) maxcount += static_cast(sketch)->getAxisCount(); - for (int i=ui->comboDirection->count()-1; i >= 2; i--) + for (int i=ui->comboDirection->count()-1; i >= 5; i--) ui->comboDirection->removeItem(i); for (int i=ui->comboDirection->count(); i < maxcount; i++) - ui->comboDirection->addItem(QString::fromLatin1("Sketch axis %1").arg(i-2)); + ui->comboDirection->addItem(QString::fromLatin1("Sketch axis %1").arg(i-5)); bool undefined = false; if (directionFeature != NULL && !directions.empty()) { @@ -171,14 +175,20 @@ void TaskLinearPatternParameters::updateUI() ui->comboDirection->setCurrentIndex(0); else if (directions.front() == "V_Axis") ui->comboDirection->setCurrentIndex(1); + else if (strcmp(directionFeature->getNameInDocument(), PartDesignGui::BaseplaneNames[0]) == 0) + ui->comboDirection->setCurrentIndex(2); + else if (strcmp(directionFeature->getNameInDocument(), PartDesignGui::BaseplaneNames[1]) == 0) + ui->comboDirection->setCurrentIndex(3); + else if (strcmp(directionFeature->getNameInDocument(), PartDesignGui::BaseplaneNames[2]) == 0) + ui->comboDirection->setCurrentIndex(4); else if (directions.front().size() > 4 && directions.front().substr(0,4) == "Axis") { - int pos = 2 + std::atoi(directions.front().substr(4,4000).c_str()); + int pos = 5 + std::atoi(directions.front().substr(4,4000).c_str()); if (pos <= maxcount) ui->comboDirection->setCurrentIndex(pos); else undefined = true; - } else if (directionFeature != NULL && !directions.empty()) { - ui->comboDirection->addItem(QString::fromLatin1(directions.front().c_str())); + } else { + ui->comboDirection->addItem(getRefStr(directionFeature, directions)); ui->comboDirection->setCurrentIndex(maxcount); } } else { @@ -186,7 +196,7 @@ void TaskLinearPatternParameters::updateUI() } if (referenceSelectionMode) { - ui->comboDirection->addItem(tr("Select an edge or a face")); + ui->comboDirection->addItem(tr("Select an edge/face or datum line/plane")); ui->comboDirection->setCurrentIndex(ui->comboDirection->count() - 1); } else if (undefined) { ui->comboDirection->addItem(tr("Undefined")); @@ -220,34 +230,33 @@ void TaskLinearPatternParameters::onSelectionChanged(const Gui::SelectionChanges if (strcmp(msg.pDocName, getObject()->getDocument()->getName()) != 0) return; - std::string subName(msg.pSubName); if (originalSelected(msg)) { ui->lineOriginal->setText(QString::fromLatin1(msg.pObjectName)); - } else if (referenceSelectionMode && - ((subName.size() > 4 && subName.substr(0,4) == "Edge") || - (subName.size() > 4 && subName.substr(0,4) == "Face"))) { - - if (strcmp(msg.pObjectName, getSupportObject()->getNameInDocument()) != 0) - return; - + } else if (referenceSelectionMode) { + // Note: ReferenceSelection has already checked the selection for validity exitSelectionMode(); if (!blockUpdate) { + std::vector directions; + App::DocumentObject* selObj; + getReferencedSelection(msg, selObj, directions); PartDesign::LinearPattern* pcLinearPattern = static_cast(getObject()); - std::vector directions(1,subName); - pcLinearPattern->Direction.setValue(getSupportObject(), directions); + pcLinearPattern->Direction.setValue(selObj, directions); recomputeFeature(); updateUI(); } else { App::DocumentObject* sketch = getSketchObject(); - int maxcount=2; + int maxcount=5; if (sketch) maxcount += static_cast(sketch)->getAxisCount(); for (int i=ui->comboDirection->count()-1; i >= maxcount; i--) ui->comboDirection->removeItem(i); - ui->comboDirection->addItem(QString::fromLatin1(subName.c_str())); + std::vector directions; + App::DocumentObject* selObj; + getReferencedSelection(msg, selObj, directions); + ui->comboDirection->addItem(getRefStr(selObj, directions)); ui->comboDirection->setCurrentIndex(maxcount); ui->comboDirection->addItem(tr("Select reference...")); } @@ -291,7 +300,7 @@ void TaskLinearPatternParameters::onDirectionChanged(int num) { PartDesign::LinearPattern* pcLinearPattern = static_cast(getObject()); App::DocumentObject* pcSketch = getSketchObject(); - int maxcount=2; + int maxcount=5; if (pcSketch) maxcount += static_cast(pcSketch)->getAxisCount(); @@ -303,8 +312,23 @@ void TaskLinearPatternParameters::onDirectionChanged(int num) { pcLinearPattern->Direction.setValue(pcSketch, std::vector(1,"V_Axis")); exitSelectionMode(); } - else if (num >= 2 && num < maxcount) { - QString buf = QString::fromUtf8("Axis%1").arg(num-2); + else if (num == 2) { + pcLinearPattern->Direction.setValue(getObject()->getDocument()->getObject(PartDesignGui::BaseplaneNames[0]), + std::vector(1,"")); + exitSelectionMode(); + } + else if (num == 3) { + pcLinearPattern->Direction.setValue(getObject()->getDocument()->getObject(PartDesignGui::BaseplaneNames[1]), + std::vector(1,"")); + exitSelectionMode(); + } + else if (num == 4) { + pcLinearPattern->Direction.setValue(getObject()->getDocument()->getObject(PartDesignGui::BaseplaneNames[2]), + std::vector(1,"")); + exitSelectionMode(); + } + else if (num >= 5 && num < maxcount) { + QString buf = QString::fromUtf8("Axis%1").arg(num-5); std::string str = buf.toStdString(); pcLinearPattern->Direction.setValue(pcSketch, std::vector(1,str)); } @@ -328,18 +352,11 @@ void TaskLinearPatternParameters::onUpdateView(bool on) if (on) { // Do the same like in TaskDlgLinearPatternParameters::accept() but without doCommand PartDesign::LinearPattern* pcLinearPattern = static_cast(getObject()); + std::vector directions; + App::DocumentObject* obj; - std::string direction = getDirection(); - if (!direction.empty()) { - std::vector directions(1,direction); - if (direction == "H_Axis" || direction == "V_Axis" || - (direction.size() > 4 && direction.substr(0,4) == "Axis")) - pcLinearPattern->Direction.setValue(getSketchObject(), directions); - else - pcLinearPattern->Direction.setValue(getSupportObject(), directions); - } else - pcLinearPattern->Direction.setValue(NULL); - + getDirection(obj, directions); + pcLinearPattern->Direction.setValue(obj,directions); pcLinearPattern->Reversed.setValue(getReverse()); pcLinearPattern->Length.setValue(getLength()); pcLinearPattern->Occurrences.setValue(getOccurrences()); @@ -348,25 +365,36 @@ void TaskLinearPatternParameters::onUpdateView(bool on) } } -const std::string TaskLinearPatternParameters::getDirection(void) const +void TaskLinearPatternParameters::getDirection(App::DocumentObject*& obj, std::vector& sub) const { - App::DocumentObject* pcSketch = getSketchObject(); - int maxcount=2; - if (pcSketch) - maxcount += static_cast(pcSketch)->getAxisCount(); + obj = getSketchObject(); + sub = std::vector(1,""); + int maxcount=5; + if (obj) + maxcount += static_cast(obj)->getAxisCount(); int num = ui->comboDirection->currentIndex(); if (num == 0) - return "H_Axis"; + sub[0] = "H_Axis"; else if (num == 1) - return "V_Axis"; - else if (num >= 2 && num < maxcount) { - QString buf = QString::fromUtf8("Axis%1").arg(num-2); - return buf.toStdString(); - } else if (num == maxcount && - ui->comboDirection->count() == maxcount + 2) - return ui->comboDirection->currentText().toStdString(); - return std::string(""); + sub[0] = "V_Axis"; + else if (num == 2) + obj = getObject()->getDocument()->getObject(PartDesignGui::BaseplaneNames[0]); + else if (num == 3) + obj = getObject()->getDocument()->getObject(PartDesignGui::BaseplaneNames[1]); + else if (num == 4) + obj = getObject()->getDocument()->getObject(PartDesignGui::BaseplaneNames[2]); + else if (num >= 5 && num < maxcount) { + QString buf = QString::fromUtf8("Axis%1").arg(num-5); + sub[0] = buf.toStdString(); + } else if (num == maxcount && ui->comboDirection->count() == maxcount + 2) { + QStringList parts = ui->comboDirection->currentText().split(QChar::fromAscii(':')); + obj = getObject()->getDocument()->getObject(parts[0].toStdString().c_str()); + if (parts.size() > 1) + sub[0] = parts[1].toStdString(); + } else { + obj = NULL; + } } const bool TaskLinearPatternParameters::getReverse(void) const @@ -403,22 +431,13 @@ void TaskLinearPatternParameters::changeEvent(QEvent *e) void TaskLinearPatternParameters::apply() { std::string name = TransformedView->getObject()->getNameInDocument(); - std::string direction = getDirection(); + std::vector directions; + App::DocumentObject* obj; + getDirection(obj, directions); + std::string direction = getPythonStr(obj, directions); if (!direction.empty()) { - App::DocumentObject* sketch = 0; - if (direction == "H_Axis" || direction == "V_Axis" || - (direction.size() > 4 && direction.substr(0,4) == "Axis")) - sketch = getSketchObject(); - else - sketch = getSupportObject(); - - if (sketch) { - QString buf = QString::fromLatin1("(App.ActiveDocument.%1,[\"%2\"])"); - buf = buf.arg(QString::fromLatin1(sketch->getNameInDocument())); - buf = buf.arg(QString::fromLatin1(direction.c_str())); - Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Direction = %s", name.c_str(), buf.toStdString().c_str()); - } + Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Direction = %s", name.c_str(), direction.c_str()); } else Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Direction = None", name.c_str()); Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Reversed = %u",name.c_str(),getReverse()); @@ -451,7 +470,6 @@ TaskDlgLinearPatternParameters::TaskDlgLinearPatternParameters(ViewProviderLinea bool TaskDlgLinearPatternParameters::accept() { try { - //Gui::Command::openCommand("LinearPattern changed"); // Handle Originals if (!TaskDlgTransformedParameters::accept()) return false; diff --git a/src/Mod/PartDesign/Gui/TaskLinearPatternParameters.cpp.orig b/src/Mod/PartDesign/Gui/TaskLinearPatternParameters.cpp.orig new file mode 100644 index 0000000000..0a982a4a8b --- /dev/null +++ b/src/Mod/PartDesign/Gui/TaskLinearPatternParameters.cpp.orig @@ -0,0 +1,511 @@ +/****************************************************************************** + * Copyright (c)2012 Jan Rheinlaender * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ******************************************************************************/ + + +#include "PreCompiled.h" + +#ifndef _PreComp_ +# include +# include +#endif + +#include "ui_TaskLinearPatternParameters.h" +#include "TaskLinearPatternParameters.h" +#include "TaskMultiTransformParameters.h" +#include "Workbench.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace PartDesignGui; +using namespace Gui; + +/* TRANSLATOR PartDesignGui::TaskLinearPatternParameters */ + +TaskLinearPatternParameters::TaskLinearPatternParameters(ViewProviderTransformed *TransformedView,QWidget *parent) + : TaskTransformedParameters(TransformedView, parent) +{ + // we need a separate container widget to add all controls to + proxy = new QWidget(this); + ui = new Ui_TaskLinearPatternParameters(); + ui->setupUi(proxy); + QMetaObject::connectSlotsByName(this); + + this->groupLayout()->addWidget(proxy); + + ui->buttonOK->hide(); + ui->checkBoxUpdateView->setEnabled(true); + + referenceSelectionMode = false; + + blockUpdate = false; // Hack, sometimes it is NOT false although set to false in Transformed::Transformed()!! + setupUI(); +} + +TaskLinearPatternParameters::TaskLinearPatternParameters(TaskMultiTransformParameters *parentTask, QLayout *layout) + : TaskTransformedParameters(parentTask) +{ + proxy = new QWidget(parentTask); + ui = new Ui_TaskLinearPatternParameters(); + ui->setupUi(proxy); + connect(ui->buttonOK, SIGNAL(pressed()), + parentTask, SLOT(onSubTaskButtonOK())); + QMetaObject::connectSlotsByName(this); + + layout->addWidget(proxy); + + ui->buttonOK->setEnabled(true); + ui->labelOriginal->hide(); + ui->lineOriginal->hide(); + ui->checkBoxUpdateView->hide(); + + referenceSelectionMode = false; + + blockUpdate = false; // Hack, sometimes it is NOT false although set to false in Transformed::Transformed()!! + setupUI(); +} + +void TaskLinearPatternParameters::setupUI() +{ + updateViewTimer = new QTimer(this); + updateViewTimer->setSingleShot(true); + updateViewTimer->setInterval(getUpdateViewTimeout()); + + connect(updateViewTimer, SIGNAL(timeout()), + this, SLOT(onUpdateViewTimer())); + connect(ui->comboDirection, SIGNAL(activated(int)), + this, SLOT(onDirectionChanged(int))); + connect(ui->checkReverse, SIGNAL(toggled(bool)), + this, SLOT(onCheckReverse(bool))); + connect(ui->spinLength, SIGNAL(valueChanged(double)), + this, SLOT(onLength(double))); + connect(ui->spinOccurrences, SIGNAL(valueChanged(uint)), + this, SLOT(onOccurrences(uint))); + connect(ui->checkBoxUpdateView, SIGNAL(toggled(bool)), + this, SLOT(onUpdateView(bool))); + + // Get the feature data + PartDesign::LinearPattern* pcLinearPattern = static_cast(getObject()); + std::vector originals = pcLinearPattern->Originals.getValues(); + + // Fill data into dialog elements + ui->lineOriginal->setEnabled(false); + for (std::vector::const_iterator i = originals.begin(); i != originals.end(); ++i) + { + if ((*i) != NULL) { // find the first valid original + ui->lineOriginal->setText(QString::fromLatin1((*i)->getNameInDocument())); + break; + } + } + // --------------------- + + ui->spinLength->bind(pcLinearPattern->Length); + ui->spinOccurrences->setMaximum(INT_MAX); + ui->spinOccurrences->bind(pcLinearPattern->Occurrences); + + ui->comboDirection->setEnabled(true); + ui->checkReverse->setEnabled(true); + ui->spinLength->blockSignals(true); + ui->spinLength->setEnabled(true); + ui->spinLength->setUnit(Base::Unit::Length); + ui->spinLength->blockSignals(false); + ui->spinOccurrences->setEnabled(true); + updateUI(); +} + +void TaskLinearPatternParameters::updateUI() +{ + if (blockUpdate) + return; + blockUpdate = true; + + PartDesign::LinearPattern* pcLinearPattern = static_cast(getObject()); + + App::DocumentObject* directionFeature = pcLinearPattern->Direction.getValue(); + std::vector directions = pcLinearPattern->Direction.getSubValues(); + bool reverse = pcLinearPattern->Reversed.getValue(); + double length = pcLinearPattern->Length.getValue(); + unsigned occurrences = pcLinearPattern->Occurrences.getValue(); + + // Add user-defined sketch axes to the reference selection combo box + App::DocumentObject* sketch = getSketchObject(); + int maxcount=5; + if (sketch) + maxcount += static_cast(sketch)->getAxisCount(); + + for (int i=ui->comboDirection->count()-1; i >= 5; i--) + ui->comboDirection->removeItem(i); + for (int i=ui->comboDirection->count(); i < maxcount; i++) +<<<<<<< 9c07d220e78d49c084d7ec2cec90f1df0572e044 + ui->comboDirection->addItem(QString::fromLatin1("Sketch axis %1").arg(i-2)); +======= + ui->comboDirection->addItem(QString::fromAscii("Sketch axis %1").arg(i-5)); +>>>>>>> Allow datum lines and planes for Transformed features' references + + bool undefined = false; + if (directionFeature != NULL && !directions.empty()) { + if (directions.front() == "H_Axis") + ui->comboDirection->setCurrentIndex(0); + else if (directions.front() == "V_Axis") + ui->comboDirection->setCurrentIndex(1); + else if (strcmp(directionFeature->getNameInDocument(), PartDesignGui::BaseplaneNames[0]) == 0) + ui->comboDirection->setCurrentIndex(2); + else if (strcmp(directionFeature->getNameInDocument(), PartDesignGui::BaseplaneNames[1]) == 0) + ui->comboDirection->setCurrentIndex(3); + else if (strcmp(directionFeature->getNameInDocument(), PartDesignGui::BaseplaneNames[2]) == 0) + ui->comboDirection->setCurrentIndex(4); + else if (directions.front().size() > 4 && directions.front().substr(0,4) == "Axis") { + int pos = 5 + std::atoi(directions.front().substr(4,4000).c_str()); + if (pos <= maxcount) + ui->comboDirection->setCurrentIndex(pos); + else + undefined = true; +<<<<<<< 9c07d220e78d49c084d7ec2cec90f1df0572e044 + } else if (directionFeature != NULL && !directions.empty()) { + ui->comboDirection->addItem(QString::fromLatin1(directions.front().c_str())); +======= + } else { + ui->comboDirection->addItem(getRefStr(directionFeature, directions)); +>>>>>>> Allow datum lines and planes for Transformed features' references + ui->comboDirection->setCurrentIndex(maxcount); + } + } else { + undefined = true; + } + + if (referenceSelectionMode) { + ui->comboDirection->addItem(tr("Select an edge/face or datum line/plane")); + ui->comboDirection->setCurrentIndex(ui->comboDirection->count() - 1); + } else if (undefined) { + ui->comboDirection->addItem(tr("Undefined")); + ui->comboDirection->setCurrentIndex(ui->comboDirection->count() - 1); + } else + ui->comboDirection->addItem(tr("Select reference...")); + + // Note: These three lines would trigger onLength(), on Occurrences() and another updateUI() if we + // didn't check for blockUpdate + ui->checkReverse->setChecked(reverse); + ui->spinLength->setValue(length); + ui->spinOccurrences->setValue(occurrences); + + blockUpdate = false; +} + +void TaskLinearPatternParameters::onUpdateViewTimer() +{ + recomputeFeature(); +} + +void TaskLinearPatternParameters::kickUpdateViewTimer() const +{ + updateViewTimer->start(); +} + +void TaskLinearPatternParameters::onSelectionChanged(const Gui::SelectionChanges& msg) +{ + if (msg.Type == Gui::SelectionChanges::AddSelection) { + + if (strcmp(msg.pDocName, getObject()->getDocument()->getName()) != 0) + return; + + if (originalSelected(msg)) { +<<<<<<< 9c07d220e78d49c084d7ec2cec90f1df0572e044 + ui->lineOriginal->setText(QString::fromLatin1(msg.pObjectName)); + } else if (referenceSelectionMode && + ((subName.size() > 4 && subName.substr(0,4) == "Edge") || + (subName.size() > 4 && subName.substr(0,4) == "Face"))) { + + if (strcmp(msg.pObjectName, getSupportObject()->getNameInDocument()) != 0) + return; + +======= + ui->lineOriginal->setText(QString::fromAscii(msg.pObjectName)); + } else if (referenceSelectionMode) { + // Note: ReferenceSelection has already checked the selection for validity +>>>>>>> Allow datum lines and planes for Transformed features' references + exitSelectionMode(); + if (!blockUpdate) { + std::vector directions; + App::DocumentObject* selObj; + getReferencedSelection(msg, selObj, directions); + PartDesign::LinearPattern* pcLinearPattern = static_cast(getObject()); + pcLinearPattern->Direction.setValue(selObj, directions); + + recomputeFeature(); + updateUI(); + } + else { + App::DocumentObject* sketch = getSketchObject(); + int maxcount=5; + if (sketch) + maxcount += static_cast(sketch)->getAxisCount(); + for (int i=ui->comboDirection->count()-1; i >= maxcount; i--) + ui->comboDirection->removeItem(i); + +<<<<<<< 9c07d220e78d49c084d7ec2cec90f1df0572e044 + ui->comboDirection->addItem(QString::fromLatin1(subName.c_str())); +======= + std::vector directions; + App::DocumentObject* selObj; + getReferencedSelection(msg, selObj, directions); + ui->comboDirection->addItem(getRefStr(selObj, directions)); +>>>>>>> Allow datum lines and planes for Transformed features' references + ui->comboDirection->setCurrentIndex(maxcount); + ui->comboDirection->addItem(tr("Select reference...")); + } + } + } +} + +void TaskLinearPatternParameters::onCheckReverse(const bool on) { + if (blockUpdate) + return; + PartDesign::LinearPattern* pcLinearPattern = static_cast(getObject()); + pcLinearPattern->Reversed.setValue(on); + + exitSelectionMode(); + kickUpdateViewTimer(); +} + +void TaskLinearPatternParameters::onLength(const double l) { + if (blockUpdate) + return; + PartDesign::LinearPattern* pcLinearPattern = static_cast(getObject()); + pcLinearPattern->Length.setValue(l); + + exitSelectionMode(); + kickUpdateViewTimer(); +} + +void TaskLinearPatternParameters::onOccurrences(const uint n) { + if (blockUpdate) + return; + PartDesign::LinearPattern* pcLinearPattern = static_cast(getObject()); + pcLinearPattern->Occurrences.setValue(n); + + exitSelectionMode(); + kickUpdateViewTimer(); +} + +void TaskLinearPatternParameters::onDirectionChanged(int num) { + if (blockUpdate) + return; + PartDesign::LinearPattern* pcLinearPattern = static_cast(getObject()); + + App::DocumentObject* pcSketch = getSketchObject(); + int maxcount=5; + if (pcSketch) + maxcount += static_cast(pcSketch)->getAxisCount(); + + if (num == 0) { + pcLinearPattern->Direction.setValue(pcSketch, std::vector(1,"H_Axis")); + exitSelectionMode(); + } + else if (num == 1) { + pcLinearPattern->Direction.setValue(pcSketch, std::vector(1,"V_Axis")); + exitSelectionMode(); + } + else if (num == 2) { + pcLinearPattern->Direction.setValue(getObject()->getDocument()->getObject(PartDesignGui::BaseplaneNames[0]), + std::vector(1,"")); + exitSelectionMode(); + } + else if (num == 3) { + pcLinearPattern->Direction.setValue(getObject()->getDocument()->getObject(PartDesignGui::BaseplaneNames[1]), + std::vector(1,"")); + exitSelectionMode(); + } + else if (num == 4) { + pcLinearPattern->Direction.setValue(getObject()->getDocument()->getObject(PartDesignGui::BaseplaneNames[2]), + std::vector(1,"")); + exitSelectionMode(); + } + else if (num >= 5 && num < maxcount) { + QString buf = QString::fromUtf8("Axis%1").arg(num-5); + std::string str = buf.toStdString(); + pcLinearPattern->Direction.setValue(pcSketch, std::vector(1,str)); + } + else if (num == ui->comboDirection->count() - 1) { + // enter reference selection mode + hideObject(); + showOriginals(); + referenceSelectionMode = true; + Gui::Selection().clearSelection(); + addReferenceSelectionGate(true, true); + } + else if (num == maxcount) + exitSelectionMode(); + + kickUpdateViewTimer(); +} + +void TaskLinearPatternParameters::onUpdateView(bool on) +{ + blockUpdate = !on; + if (on) { + // Do the same like in TaskDlgLinearPatternParameters::accept() but without doCommand + PartDesign::LinearPattern* pcLinearPattern = static_cast(getObject()); + std::vector directions; + App::DocumentObject* obj; + + getDirection(obj, directions); + pcLinearPattern->Direction.setValue(obj,directions); + pcLinearPattern->Reversed.setValue(getReverse()); + pcLinearPattern->Length.setValue(getLength()); + pcLinearPattern->Occurrences.setValue(getOccurrences()); + + recomputeFeature(); + } +} + +void TaskLinearPatternParameters::getDirection(App::DocumentObject*& obj, std::vector& sub) const +{ + obj = getSketchObject(); + sub = std::vector(1,""); + int maxcount=5; + if (obj) + maxcount += static_cast(obj)->getAxisCount(); + + int num = ui->comboDirection->currentIndex(); + if (num == 0) + sub[0] = "H_Axis"; + else if (num == 1) + sub[0] = "V_Axis"; + else if (num == 2) + obj = getObject()->getDocument()->getObject(PartDesignGui::BaseplaneNames[0]); + else if (num == 3) + obj = getObject()->getDocument()->getObject(PartDesignGui::BaseplaneNames[1]); + else if (num == 4) + obj = getObject()->getDocument()->getObject(PartDesignGui::BaseplaneNames[2]); + else if (num >= 5 && num < maxcount) { + QString buf = QString::fromUtf8("Axis%1").arg(num-5); + sub[0] = buf.toStdString(); + } else if (num == maxcount && ui->comboDirection->count() == maxcount + 2) { + QStringList parts = ui->comboDirection->currentText().split(QChar::fromAscii(':')); + obj = getObject()->getDocument()->getObject(parts[0].toStdString().c_str()); + if (parts.size() > 1) + sub[0] = parts[1].toStdString(); + } else { + obj = NULL; + } +} + +const bool TaskLinearPatternParameters::getReverse(void) const +{ + return ui->checkReverse->isChecked(); +} + +const double TaskLinearPatternParameters::getLength(void) const +{ + return ui->spinLength->value().getValue(); +} + +const unsigned TaskLinearPatternParameters::getOccurrences(void) const +{ + return ui->spinOccurrences->value(); +} + + +TaskLinearPatternParameters::~TaskLinearPatternParameters() +{ + delete ui; + if (proxy) + delete proxy; +} + +void TaskLinearPatternParameters::changeEvent(QEvent *e) +{ + TaskBox::changeEvent(e); + if (e->type() == QEvent::LanguageChange) { + ui->retranslateUi(proxy); + } +} + +void TaskLinearPatternParameters::apply() +{ + std::string name = TransformedView->getObject()->getNameInDocument(); + + std::vector directions; + App::DocumentObject* obj; + getDirection(obj, directions); + std::string direction = getPythonStr(obj, directions); + if (!direction.empty()) { + Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Direction = %s", name.c_str(), direction.c_str()); + } else + Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Direction = None", name.c_str()); + Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Reversed = %u",name.c_str(),getReverse()); + + ui->spinLength->apply(); + ui->spinOccurrences->apply(); + + Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.recompute()"); + if (!TransformedView->getObject()->isValid()) + throw Base::Exception(TransformedView->getObject()->getStatusString()); + Gui::Command::doCommand(Gui::Command::Gui,"Gui.activeDocument().resetEdit()"); + Gui::Command::commitCommand(); +} + +//************************************************************************** +//************************************************************************** +// TaskDialog +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +TaskDlgLinearPatternParameters::TaskDlgLinearPatternParameters(ViewProviderLinearPattern *LinearPatternView) + : TaskDlgTransformedParameters(LinearPatternView) +{ + parameter = new TaskLinearPatternParameters(LinearPatternView); + + Content.push_back(parameter); +} + +//==== calls from the TaskView =============================================================== + +bool TaskDlgLinearPatternParameters::accept() +{ + try { + // Handle Originals + if (!TaskDlgTransformedParameters::accept()) + return false; + + parameter->apply(); + } + catch (const Base::Exception& e) { + QMessageBox::warning(parameter, tr("Input error"), QString::fromLatin1(e.what())); + return false; + } + + return true; +} + +#include "moc_TaskLinearPatternParameters.cpp" diff --git a/src/Mod/PartDesign/Gui/TaskLinearPatternParameters.h b/src/Mod/PartDesign/Gui/TaskLinearPatternParameters.h index 2f557357d8..5bf80e256c 100644 --- a/src/Mod/PartDesign/Gui/TaskLinearPatternParameters.h +++ b/src/Mod/PartDesign/Gui/TaskLinearPatternParameters.h @@ -70,7 +70,7 @@ private Q_SLOTS: protected: virtual void changeEvent(QEvent *e); virtual void onSelectionChanged(const Gui::SelectionChanges& msg); - const std::string getDirection(void) const; + void getDirection(App::DocumentObject*& obj, std::vector& sub) const; const bool getReverse(void) const; const double getLength(void) const; const unsigned getOccurrences(void) const; diff --git a/src/Mod/PartDesign/Gui/TaskLinearPatternParameters.ui b/src/Mod/PartDesign/Gui/TaskLinearPatternParameters.ui index b1ad7ce8e1..dff273eb89 100644 --- a/src/Mod/PartDesign/Gui/TaskLinearPatternParameters.ui +++ b/src/Mod/PartDesign/Gui/TaskLinearPatternParameters.ui @@ -6,7 +6,7 @@ 0 0 - 260 + 266 402 @@ -49,6 +49,21 @@ Vertical sketch axis + + + Base plane XY + + + + + Base plane XZ + + + + + Base plane YZ + + Select reference... diff --git a/src/Mod/PartDesign/Gui/TaskMirroredParameters.cpp b/src/Mod/PartDesign/Gui/TaskMirroredParameters.cpp index eae21f844d..a1da163966 100644 --- a/src/Mod/PartDesign/Gui/TaskMirroredParameters.cpp +++ b/src/Mod/PartDesign/Gui/TaskMirroredParameters.cpp @@ -30,6 +30,7 @@ #include "ui_TaskMirroredParameters.h" #include "TaskMirroredParameters.h" #include "TaskMultiTransformParameters.h" +#include "Workbench.h" #include #include #include @@ -40,6 +41,7 @@ #include #include #include +#include #include #include @@ -56,7 +58,7 @@ TaskMirroredParameters::TaskMirroredParameters(ViewProviderTransformed *Transfor ui = new Ui_TaskMirroredParameters(); ui->setupUi(proxy); QMetaObject::connectSlotsByName(this); - + this->groupLayout()->addWidget(proxy); ui->buttonOK->hide(); @@ -119,24 +121,25 @@ void TaskMirroredParameters::setupUI() void TaskMirroredParameters::updateUI() { - if (blockUpdate) + if (blockUpdate) return; blockUpdate = true; - + PartDesign::Mirrored* pcMirrored = static_cast(getObject()); - + App::DocumentObject* mirrorPlaneFeature = pcMirrored->MirrorPlane.getValue(); std::vector mirrorPlanes = pcMirrored->MirrorPlane.getSubValues(); - + + // Add user-defined sketch axes to the reference selection combo box App::DocumentObject* sketch = getSketchObject(); - int maxcount=2; + int maxcount=5; if (sketch) maxcount += static_cast(sketch)->getAxisCount(); - for (int i=ui->comboPlane->count()-1; i >= 2; i--) + for (int i=ui->comboPlane->count()-1; i >= 5; i--) ui->comboPlane->removeItem(i); for (int i=ui->comboPlane->count(); i < maxcount; i++) - ui->comboPlane->addItem(QString::fromLatin1("Sketch axis %1").arg(i-2)); + ui->comboPlane->addItem(QString::fromLatin1("Sketch axis %1").arg(i-5)); bool undefined = false; if (mirrorPlaneFeature != NULL && !mirrorPlanes.empty()) { @@ -144,22 +147,28 @@ void TaskMirroredParameters::updateUI() ui->comboPlane->setCurrentIndex(0); else if (mirrorPlanes.front() == "V_Axis") ui->comboPlane->setCurrentIndex(1); + else if (strcmp(mirrorPlaneFeature->getNameInDocument(), PartDesignGui::BaseplaneNames[0]) == 0) + ui->comboPlane->setCurrentIndex(2); + else if (strcmp(mirrorPlaneFeature->getNameInDocument(), PartDesignGui::BaseplaneNames[1]) == 0) + ui->comboPlane->setCurrentIndex(3); + else if (strcmp(mirrorPlaneFeature->getNameInDocument(), PartDesignGui::BaseplaneNames[2]) == 0) + ui->comboPlane->setCurrentIndex(4); else if (mirrorPlanes.front().size() > 4 && mirrorPlanes.front().substr(0,4) == "Axis") { - int pos = 2 + std::atoi(mirrorPlanes.front().substr(4,4000).c_str()); + int pos = 5 + std::atoi(mirrorPlanes.front().substr(4,4000).c_str()); if (pos <= maxcount) ui->comboPlane->setCurrentIndex(pos); else undefined = true; - } else if (mirrorPlaneFeature != NULL && !mirrorPlanes.empty()) { - ui->comboPlane->addItem(QString::fromLatin1(mirrorPlanes.front().c_str())); - ui->comboPlane->setCurrentIndex(maxcount); + } else { + ui->comboPlane->addItem(getRefStr(mirrorPlaneFeature, mirrorPlanes)); + ui->comboPlane->setCurrentIndex(maxcount); } } else { undefined = true; } - + if (referenceSelectionMode) { - ui->comboPlane->addItem(tr("Select a face")); + ui->comboPlane->addItem(tr("Select a face or datum plane")); ui->comboPlane->setCurrentIndex(ui->comboPlane->count() - 1); } else if (undefined) { ui->comboPlane->addItem(tr("Undefined")); @@ -177,33 +186,33 @@ void TaskMirroredParameters::onSelectionChanged(const Gui::SelectionChanges& msg if (strcmp(msg.pDocName, getObject()->getDocument()->getName()) != 0) return; - std::string subName(msg.pSubName); if (originalSelected(msg)) { ui->lineOriginal->setText(QString::fromLatin1(msg.pObjectName)); - } else if (referenceSelectionMode && - (subName.size() > 4 && subName.substr(0,4) == "Face")) { - - if (strcmp(msg.pObjectName, getSupportObject()->getNameInDocument()) != 0) - return; - + } else if (referenceSelectionMode) { + // Note: ReferenceSelection has already checked the selection for validity exitSelectionMode(); if (!blockUpdate) { + std::vector mirrorPlanes; + App::DocumentObject* selObj; + getReferencedSelection(msg, selObj, mirrorPlanes); PartDesign::Mirrored* pcMirrored = static_cast(getObject()); - std::vector mirrorPlanes(1,subName); - pcMirrored->MirrorPlane.setValue(getSupportObject(), mirrorPlanes); + pcMirrored->MirrorPlane.setValue(selObj, mirrorPlanes); recomputeFeature(); updateUI(); } else { App::DocumentObject* sketch = getSketchObject(); - int maxcount=2; + int maxcount=5; if (sketch) maxcount += static_cast(sketch)->getAxisCount(); for (int i=ui->comboPlane->count()-1; i >= maxcount; i--) ui->comboPlane->removeItem(i); - ui->comboPlane->addItem(QString::fromLatin1(subName.c_str())); + std::vector mirrorPlanes; + App::DocumentObject* selObj; + getReferencedSelection(msg, selObj, mirrorPlanes); + ui->comboPlane->addItem(getRefStr(selObj, mirrorPlanes)); ui->comboPlane->setCurrentIndex(maxcount); ui->comboPlane->addItem(tr("Select reference...")); } @@ -212,12 +221,12 @@ void TaskMirroredParameters::onSelectionChanged(const Gui::SelectionChanges& msg } void TaskMirroredParameters::onPlaneChanged(int num) { - if (blockUpdate) + if (blockUpdate) return; PartDesign::Mirrored* pcMirrored = static_cast(getObject()); - + App::DocumentObject* pcSketch = getSketchObject(); - int maxcount=2; + int maxcount=5; if (pcSketch) maxcount += static_cast(pcSketch)->getAxisCount(); @@ -229,8 +238,23 @@ void TaskMirroredParameters::onPlaneChanged(int num) { pcMirrored->MirrorPlane.setValue(pcSketch, std::vector(1,"V_Axis")); exitSelectionMode(); } - else if (num >= 2 && num < maxcount) { - QString buf = QString::fromUtf8("Axis%1").arg(num-2); + else if (num == 2) { + pcMirrored->MirrorPlane.setValue(getObject()->getDocument()->getObject(PartDesignGui::BaseplaneNames[0]), + std::vector(1,"")); + exitSelectionMode(); + } + else if (num == 3) { + pcMirrored->MirrorPlane.setValue(getObject()->getDocument()->getObject(PartDesignGui::BaseplaneNames[1]), + std::vector(1,"")); + exitSelectionMode(); + } + else if (num == 4) { + pcMirrored->MirrorPlane.setValue(getObject()->getDocument()->getObject(PartDesignGui::BaseplaneNames[2]), + std::vector(1,"")); + exitSelectionMode(); + } + else if (num >= 5 && num < maxcount) { + QString buf = QString::fromUtf8("Axis%1").arg(num-5); std::string str = buf.toStdString(); pcMirrored->MirrorPlane.setValue(pcSketch, std::vector(1,str)); } @@ -244,7 +268,7 @@ void TaskMirroredParameters::onPlaneChanged(int num) { } else if (num == maxcount) exitSelectionMode(); - + recomputeFeature(); } @@ -254,41 +278,46 @@ void TaskMirroredParameters::onUpdateView(bool on) if (on) { // Do the same like in TaskDlgMirroredParameters::accept() but without doCommand PartDesign::Mirrored* pcMirrored = static_cast(getObject()); + std::vector mirrorPlanes; + App::DocumentObject* obj; - std::string mirrorPlane = getMirrorPlane(); - if (!mirrorPlane.empty()) { - std::vector planes(1,mirrorPlane); - if (mirrorPlane == "H_Axis" || mirrorPlane == "V_Axis" || - (mirrorPlane.size() > 4 && mirrorPlane.substr(0,4) == "Axis")) - pcMirrored->MirrorPlane.setValue(getSketchObject(),planes); - else - pcMirrored->MirrorPlane.setValue(getSupportObject(),planes); - } else - pcMirrored->MirrorPlane.setValue(NULL); + getMirrorPlane(obj, mirrorPlanes); + pcMirrored->MirrorPlane.setValue(obj,mirrorPlanes); recomputeFeature(); } } -const std::string TaskMirroredParameters::getMirrorPlane(void) const +void TaskMirroredParameters::getMirrorPlane(App::DocumentObject*& obj, std::vector& sub) const { - App::DocumentObject* pcSketch = getSketchObject(); - int maxcount=2; - if (pcSketch) - maxcount += static_cast(pcSketch)->getAxisCount(); - + obj = getSketchObject(); + sub = std::vector(1,""); + int maxcount=5; + if (obj) + maxcount += static_cast(obj)->getAxisCount(); + int num = ui->comboPlane->currentIndex(); if (num == 0) - return "H_Axis"; + sub[0] = "H_Axis"; else if (num == 1) - return "V_Axis"; - else if (num >= 2 && num < maxcount) { - QString buf = QString::fromUtf8("Axis%1").arg(num-2); - return buf.toStdString(); - } else if (num == maxcount && - ui->comboPlane->count() == maxcount + 2) - return ui->comboPlane->currentText().toStdString(); - return std::string(""); + sub[0] = "V_Axis"; + else if (num == 2) + obj = getObject()->getDocument()->getObject(PartDesignGui::BaseplaneNames[0]); + else if (num == 3) + obj = getObject()->getDocument()->getObject(PartDesignGui::BaseplaneNames[1]); + else if (num == 4) + obj = getObject()->getDocument()->getObject(PartDesignGui::BaseplaneNames[2]); + else if (num >= 5 && num < maxcount) { + QString buf = QString::fromUtf8("Axis%1").arg(num-5); + sub[0] = buf.toStdString(); + } else if (num == maxcount && ui->comboPlane->count() == maxcount + 2) { + QStringList parts = ui->comboPlane->currentText().split(QChar::fromAscii(':')); + obj = getObject()->getDocument()->getObject(parts[0].toStdString().c_str()); + if (parts.size() > 1) + sub[0] = parts[1].toStdString(); + } else { + obj = NULL; + } } void TaskMirroredParameters::apply() @@ -329,29 +358,19 @@ bool TaskDlgMirroredParameters::accept() std::string name = TransformedView->getObject()->getNameInDocument(); try { - //Gui::Command::openCommand("Mirrored changed"); - // Handle Originals + // Handle Originals if (!TaskDlgTransformedParameters::accept()) return false; TaskMirroredParameters* mirrorParameter = static_cast(parameter); - std::string mirrorPlane = mirrorParameter->getMirrorPlane(); + std::vector mirrorPlanes; + App::DocumentObject* obj; + mirrorParameter->getMirrorPlane(obj, mirrorPlanes); + std::string mirrorPlane = mirrorParameter->getPythonStr(obj, mirrorPlanes); if (!mirrorPlane.empty()) { - App::DocumentObject* sketch = 0; - if (mirrorPlane == "H_Axis" || mirrorPlane == "V_Axis" || - (mirrorPlane.size() > 4 && mirrorPlane.substr(0,4) == "Axis")) - sketch = mirrorParameter->getSketchObject(); - else - sketch = mirrorParameter->getSupportObject(); - - if (sketch) { - QString buf = QString::fromLatin1("(App.ActiveDocument.%1,[\"%2\"])"); - buf = buf.arg(QString::fromLatin1(sketch->getNameInDocument())); - buf = buf.arg(QString::fromLatin1(mirrorPlane.c_str())); - Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.MirrorPlane = %s", name.c_str(), buf.toStdString().c_str()); - } + Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.MirrorPlane = %s", name.c_str(), mirrorPlane.c_str()); } else - Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.MirrorPlane = None", name.c_str()); + Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.MirrorPlane = None", name.c_str()); Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.recompute()"); if (!TransformedView->getObject()->isValid()) throw Base::Exception(TransformedView->getObject()->getStatusString()); diff --git a/src/Mod/PartDesign/Gui/TaskMirroredParameters.cpp.orig b/src/Mod/PartDesign/Gui/TaskMirroredParameters.cpp.orig new file mode 100644 index 0000000000..c3ae4235c1 --- /dev/null +++ b/src/Mod/PartDesign/Gui/TaskMirroredParameters.cpp.orig @@ -0,0 +1,412 @@ +/****************************************************************************** + * Copyright (c)2012 Jan Rheinlaender * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ******************************************************************************/ + + +#include "PreCompiled.h" + +#ifndef _PreComp_ +# include +#endif + +#include "ui_TaskMirroredParameters.h" +#include "TaskMirroredParameters.h" +#include "TaskMultiTransformParameters.h" +#include "Workbench.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace PartDesignGui; +using namespace Gui; + +/* TRANSLATOR PartDesignGui::TaskMirroredParameters */ + +TaskMirroredParameters::TaskMirroredParameters(ViewProviderTransformed *TransformedView, QWidget *parent) + : TaskTransformedParameters(TransformedView, parent) +{ + // we need a separate container widget to add all controls to + proxy = new QWidget(this); + ui = new Ui_TaskMirroredParameters(); + ui->setupUi(proxy); + QMetaObject::connectSlotsByName(this); + + this->groupLayout()->addWidget(proxy); + + ui->buttonOK->hide(); + ui->checkBoxUpdateView->setEnabled(true); + + referenceSelectionMode = false; + + blockUpdate = false; // Hack, sometimes it is NOT false although set to false in Transformed::Transformed()!! + setupUI(); +} + +TaskMirroredParameters::TaskMirroredParameters(TaskMultiTransformParameters *parentTask, QLayout *layout) + : TaskTransformedParameters(parentTask) +{ + proxy = new QWidget(parentTask); + ui = new Ui_TaskMirroredParameters(); + ui->setupUi(proxy); + connect(ui->buttonOK, SIGNAL(pressed()), + parentTask, SLOT(onSubTaskButtonOK())); + QMetaObject::connectSlotsByName(this); + + layout->addWidget(proxy); + + ui->buttonOK->setEnabled(true); + ui->labelOriginal->hide(); + ui->lineOriginal->hide(); + ui->checkBoxUpdateView->hide(); + + referenceSelectionMode = false; + + blockUpdate = false; // Hack, sometimes it is NOT false although set to false in Transformed::Transformed()!! + setupUI(); +} + +void TaskMirroredParameters::setupUI() +{ + connect(ui->comboPlane, SIGNAL(activated(int)), + this, SLOT(onPlaneChanged(int))); + connect(ui->checkBoxUpdateView, SIGNAL(toggled(bool)), + this, SLOT(onUpdateView(bool))); + + // Get the feature data + PartDesign::Mirrored* pcMirrored = static_cast(getObject()); + std::vector originals = pcMirrored->Originals.getValues(); + + // Fill data into dialog elements + ui->lineOriginal->setEnabled(false); + for (std::vector::const_iterator i = originals.begin(); i != originals.end(); ++i) + { + if ((*i) != NULL) { // find the first valid original + ui->lineOriginal->setText(QString::fromLatin1((*i)->getNameInDocument())); + break; + } + } + // --------------------- + + ui->comboPlane->setEnabled(true); + updateUI(); +} + +void TaskMirroredParameters::updateUI() +{ + if (blockUpdate) + return; + blockUpdate = true; + + PartDesign::Mirrored* pcMirrored = static_cast(getObject()); + + App::DocumentObject* mirrorPlaneFeature = pcMirrored->MirrorPlane.getValue(); + std::vector mirrorPlanes = pcMirrored->MirrorPlane.getSubValues(); + + // Add user-defined sketch axes to the reference selection combo box + App::DocumentObject* sketch = getSketchObject(); + int maxcount=5; + if (sketch) + maxcount += static_cast(sketch)->getAxisCount(); + + for (int i=ui->comboPlane->count()-1; i >= 5; i--) + ui->comboPlane->removeItem(i); + for (int i=ui->comboPlane->count(); i < maxcount; i++) +<<<<<<< 9c07d220e78d49c084d7ec2cec90f1df0572e044 + ui->comboPlane->addItem(QString::fromLatin1("Sketch axis %1").arg(i-2)); +======= + ui->comboPlane->addItem(QString::fromAscii("Sketch axis %1").arg(i-5)); +>>>>>>> Allow datum lines and planes for Transformed features' references + + bool undefined = false; + if (mirrorPlaneFeature != NULL && !mirrorPlanes.empty()) { + if (mirrorPlanes.front() == "H_Axis") + ui->comboPlane->setCurrentIndex(0); + else if (mirrorPlanes.front() == "V_Axis") + ui->comboPlane->setCurrentIndex(1); + else if (strcmp(mirrorPlaneFeature->getNameInDocument(), PartDesignGui::BaseplaneNames[0]) == 0) + ui->comboPlane->setCurrentIndex(2); + else if (strcmp(mirrorPlaneFeature->getNameInDocument(), PartDesignGui::BaseplaneNames[1]) == 0) + ui->comboPlane->setCurrentIndex(3); + else if (strcmp(mirrorPlaneFeature->getNameInDocument(), PartDesignGui::BaseplaneNames[2]) == 0) + ui->comboPlane->setCurrentIndex(4); + else if (mirrorPlanes.front().size() > 4 && mirrorPlanes.front().substr(0,4) == "Axis") { + int pos = 5 + std::atoi(mirrorPlanes.front().substr(4,4000).c_str()); + if (pos <= maxcount) + ui->comboPlane->setCurrentIndex(pos); + else + undefined = true; +<<<<<<< 9c07d220e78d49c084d7ec2cec90f1df0572e044 + } else if (mirrorPlaneFeature != NULL && !mirrorPlanes.empty()) { + ui->comboPlane->addItem(QString::fromLatin1(mirrorPlanes.front().c_str())); + ui->comboPlane->setCurrentIndex(maxcount); +======= + } else { + ui->comboPlane->addItem(getRefStr(mirrorPlaneFeature, mirrorPlanes)); + ui->comboPlane->setCurrentIndex(maxcount); +>>>>>>> Allow datum lines and planes for Transformed features' references + } + } else { + undefined = true; + } + + if (referenceSelectionMode) { + ui->comboPlane->addItem(tr("Select a face or datum plane")); + ui->comboPlane->setCurrentIndex(ui->comboPlane->count() - 1); + } else if (undefined) { + ui->comboPlane->addItem(tr("Undefined")); + ui->comboPlane->setCurrentIndex(ui->comboPlane->count() - 1); + } else + ui->comboPlane->addItem(tr("Select reference...")); + + blockUpdate = false; +} + +void TaskMirroredParameters::onSelectionChanged(const Gui::SelectionChanges& msg) +{ + if (msg.Type == Gui::SelectionChanges::AddSelection) { + + if (strcmp(msg.pDocName, getObject()->getDocument()->getName()) != 0) + return; + + if (originalSelected(msg)) { +<<<<<<< 9c07d220e78d49c084d7ec2cec90f1df0572e044 + ui->lineOriginal->setText(QString::fromLatin1(msg.pObjectName)); + } else if (referenceSelectionMode && + (subName.size() > 4 && subName.substr(0,4) == "Face")) { + + if (strcmp(msg.pObjectName, getSupportObject()->getNameInDocument()) != 0) + return; + +======= + ui->lineOriginal->setText(QString::fromAscii(msg.pObjectName)); + } else if (referenceSelectionMode) { + // Note: ReferenceSelection has already checked the selection for validity +>>>>>>> Allow datum lines and planes for Transformed features' references + exitSelectionMode(); + if (!blockUpdate) { + std::vector mirrorPlanes; + App::DocumentObject* selObj; + getReferencedSelection(msg, selObj, mirrorPlanes); + PartDesign::Mirrored* pcMirrored = static_cast(getObject()); + pcMirrored->MirrorPlane.setValue(selObj, mirrorPlanes); + + recomputeFeature(); + updateUI(); + } + else { + App::DocumentObject* sketch = getSketchObject(); + int maxcount=5; + if (sketch) + maxcount += static_cast(sketch)->getAxisCount(); + for (int i=ui->comboPlane->count()-1; i >= maxcount; i--) + ui->comboPlane->removeItem(i); + +<<<<<<< 9c07d220e78d49c084d7ec2cec90f1df0572e044 + ui->comboPlane->addItem(QString::fromLatin1(subName.c_str())); +======= + std::vector mirrorPlanes; + App::DocumentObject* selObj; + getReferencedSelection(msg, selObj, mirrorPlanes); + ui->comboPlane->addItem(getRefStr(selObj, mirrorPlanes)); +>>>>>>> Allow datum lines and planes for Transformed features' references + ui->comboPlane->setCurrentIndex(maxcount); + ui->comboPlane->addItem(tr("Select reference...")); + } + } + } +} + +void TaskMirroredParameters::onPlaneChanged(int num) { + if (blockUpdate) + return; + PartDesign::Mirrored* pcMirrored = static_cast(getObject()); + + App::DocumentObject* pcSketch = getSketchObject(); + int maxcount=5; + if (pcSketch) + maxcount += static_cast(pcSketch)->getAxisCount(); + + if (num == 0) { + pcMirrored->MirrorPlane.setValue(pcSketch, std::vector(1,"H_Axis")); + exitSelectionMode(); + } + else if (num == 1) { + pcMirrored->MirrorPlane.setValue(pcSketch, std::vector(1,"V_Axis")); + exitSelectionMode(); + } + else if (num == 2) { + pcMirrored->MirrorPlane.setValue(getObject()->getDocument()->getObject(PartDesignGui::BaseplaneNames[0]), + std::vector(1,"")); + exitSelectionMode(); + } + else if (num == 3) { + pcMirrored->MirrorPlane.setValue(getObject()->getDocument()->getObject(PartDesignGui::BaseplaneNames[1]), + std::vector(1,"")); + exitSelectionMode(); + } + else if (num == 4) { + pcMirrored->MirrorPlane.setValue(getObject()->getDocument()->getObject(PartDesignGui::BaseplaneNames[2]), + std::vector(1,"")); + exitSelectionMode(); + } + else if (num >= 5 && num < maxcount) { + QString buf = QString::fromUtf8("Axis%1").arg(num-5); + std::string str = buf.toStdString(); + pcMirrored->MirrorPlane.setValue(pcSketch, std::vector(1,str)); + } + else if (num == ui->comboPlane->count() - 1) { + // enter reference selection mode + hideObject(); + showOriginals(); + referenceSelectionMode = true; + Gui::Selection().clearSelection(); + addReferenceSelectionGate(false, true); + } + else if (num == maxcount) + exitSelectionMode(); + + recomputeFeature(); +} + +void TaskMirroredParameters::onUpdateView(bool on) +{ + blockUpdate = !on; + if (on) { + // Do the same like in TaskDlgMirroredParameters::accept() but without doCommand + PartDesign::Mirrored* pcMirrored = static_cast(getObject()); + std::vector mirrorPlanes; + App::DocumentObject* obj; + + getMirrorPlane(obj, mirrorPlanes); + pcMirrored->MirrorPlane.setValue(obj,mirrorPlanes); + + recomputeFeature(); + } +} + +void TaskMirroredParameters::getMirrorPlane(App::DocumentObject*& obj, std::vector& sub) const +{ + obj = getSketchObject(); + sub = std::vector(1,""); + int maxcount=5; + if (obj) + maxcount += static_cast(obj)->getAxisCount(); + + int num = ui->comboPlane->currentIndex(); + if (num == 0) + sub[0] = "H_Axis"; + else if (num == 1) + sub[0] = "V_Axis"; + else if (num == 2) + obj = getObject()->getDocument()->getObject(PartDesignGui::BaseplaneNames[0]); + else if (num == 3) + obj = getObject()->getDocument()->getObject(PartDesignGui::BaseplaneNames[1]); + else if (num == 4) + obj = getObject()->getDocument()->getObject(PartDesignGui::BaseplaneNames[2]); + else if (num >= 5 && num < maxcount) { + QString buf = QString::fromUtf8("Axis%1").arg(num-5); + sub[0] = buf.toStdString(); + } else if (num == maxcount && ui->comboPlane->count() == maxcount + 2) { + QStringList parts = ui->comboPlane->currentText().split(QChar::fromAscii(':')); + obj = getObject()->getDocument()->getObject(parts[0].toStdString().c_str()); + if (parts.size() > 1) + sub[0] = parts[1].toStdString(); + } else { + obj = NULL; + } +} + +void TaskMirroredParameters::apply() +{ +} + +TaskMirroredParameters::~TaskMirroredParameters() +{ + delete ui; + if (proxy) + delete proxy; +} + +void TaskMirroredParameters::changeEvent(QEvent *e) +{ + TaskBox::changeEvent(e); + if (e->type() == QEvent::LanguageChange) { + ui->retranslateUi(proxy); + } +} + +//************************************************************************** +//************************************************************************** +// TaskDialog +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +TaskDlgMirroredParameters::TaskDlgMirroredParameters(ViewProviderMirrored *MirroredView) + : TaskDlgTransformedParameters(MirroredView) +{ + parameter = new TaskMirroredParameters(MirroredView); + + Content.push_back(parameter); +} +//==== calls from the TaskView =============================================================== + +bool TaskDlgMirroredParameters::accept() +{ + std::string name = TransformedView->getObject()->getNameInDocument(); + + try { + // Handle Originals + if (!TaskDlgTransformedParameters::accept()) + return false; + + TaskMirroredParameters* mirrorParameter = static_cast(parameter); + std::vector mirrorPlanes; + App::DocumentObject* obj; + mirrorParameter->getMirrorPlane(obj, mirrorPlanes); + std::string mirrorPlane = mirrorParameter->getPythonStr(obj, mirrorPlanes); + if (!mirrorPlane.empty()) { + Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.MirrorPlane = %s", name.c_str(), mirrorPlane.c_str()); + } else + Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.MirrorPlane = None", name.c_str()); + Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.recompute()"); + if (!TransformedView->getObject()->isValid()) + throw Base::Exception(TransformedView->getObject()->getStatusString()); + Gui::Command::doCommand(Gui::Command::Gui,"Gui.activeDocument().resetEdit()"); + Gui::Command::commitCommand(); + } + catch (const Base::Exception& e) { + QMessageBox::warning(parameter, tr("Input error"), QString::fromLatin1(e.what())); + return false; + } + + return true; +} + +#include "moc_TaskMirroredParameters.cpp" diff --git a/src/Mod/PartDesign/Gui/TaskMirroredParameters.h b/src/Mod/PartDesign/Gui/TaskMirroredParameters.h index 3312662fa3..fa56829ed9 100644 --- a/src/Mod/PartDesign/Gui/TaskMirroredParameters.h +++ b/src/Mod/PartDesign/Gui/TaskMirroredParameters.h @@ -57,7 +57,7 @@ public: virtual ~TaskMirroredParameters(); - const std::string getMirrorPlane(void) const; + void getMirrorPlane(App::DocumentObject*& obj, std::vector& sub) const; virtual void apply(); diff --git a/src/Mod/PartDesign/Gui/TaskMirroredParameters.ui b/src/Mod/PartDesign/Gui/TaskMirroredParameters.ui index f0f2e8d7d7..461ca5e07f 100644 --- a/src/Mod/PartDesign/Gui/TaskMirroredParameters.ui +++ b/src/Mod/PartDesign/Gui/TaskMirroredParameters.ui @@ -6,7 +6,7 @@ 0 0 - 218 + 242 290 @@ -49,6 +49,21 @@ Vertical sketch axis + + + Base plane XY + + + + + Base plane XZ + + + + + Base plane YZ + + Select reference... diff --git a/src/Mod/PartDesign/Gui/TaskPolarPatternParameters.cpp b/src/Mod/PartDesign/Gui/TaskPolarPatternParameters.cpp index 8e556d8145..967fb4567a 100644 --- a/src/Mod/PartDesign/Gui/TaskPolarPatternParameters.cpp +++ b/src/Mod/PartDesign/Gui/TaskPolarPatternParameters.cpp @@ -31,6 +31,7 @@ #include "ui_TaskPolarPatternParameters.h" #include "TaskPolarPatternParameters.h" #include "TaskMultiTransformParameters.h" +#include "Workbench.h" #include #include #include @@ -44,6 +45,7 @@ #include #include #include +#include using namespace PartDesignGui; using namespace Gui; @@ -158,8 +160,8 @@ void TaskPolarPatternParameters::updateUI() if (axisFeature != NULL && !axes.empty()) { if (axes.front() == "N_Axis") ui->comboAxis->setCurrentIndex(0); - else if (axisFeature != NULL && !axes.empty()) { - ui->comboAxis->addItem(QString::fromLatin1(axes.front().c_str())); + else { + ui->comboAxis->addItem(getRefStr(axisFeature, axes)); ui->comboAxis->setCurrentIndex(1); } } else { @@ -167,7 +169,7 @@ void TaskPolarPatternParameters::updateUI() } if (referenceSelectionMode) { - ui->comboAxis->addItem(tr("Select an edge")); + ui->comboAxis->addItem(tr("Select an edge or datum line")); ui->comboAxis->setCurrentIndex(ui->comboAxis->count() - 1); } else ui->comboAxis->addItem(tr("Select reference...")); @@ -198,20 +200,17 @@ void TaskPolarPatternParameters::onSelectionChanged(const Gui::SelectionChanges& if (strcmp(msg.pDocName, getObject()->getDocument()->getName()) != 0) return; - std::string subName(msg.pSubName); if (originalSelected(msg)) { ui->lineOriginal->setText(QString::fromLatin1(msg.pObjectName)); - } else if (referenceSelectionMode && - (subName.size() > 4 && subName.substr(0,4) == "Edge")) { - - if (strcmp(msg.pObjectName, getSupportObject()->getNameInDocument()) != 0) - return; - + } else if (referenceSelectionMode) { + // Note: ReferenceSelection has already checked the selection for validity exitSelectionMode(); if (!blockUpdate) { + std::vector axes; + App::DocumentObject* selObj; + getReferencedSelection(msg, selObj, axes); PartDesign::PolarPattern* pcPolarPattern = static_cast(getObject()); - std::vector axes(1,subName); - pcPolarPattern->Axis.setValue(getSupportObject(), axes); + pcPolarPattern->Axis.setValue(selObj, axes); recomputeFeature(); updateUI(); @@ -220,7 +219,10 @@ void TaskPolarPatternParameters::onSelectionChanged(const Gui::SelectionChanges& for (int i=ui->comboAxis->count()-1; i >= 1; i--) ui->comboAxis->removeItem(i); - ui->comboAxis->addItem(QString::fromLatin1(subName.c_str())); + std::vector axes; + App::DocumentObject* selObj; + getReferencedSelection(msg, selObj, axes); + ui->comboAxis->addItem(getRefStr(selObj, axes)); ui->comboAxis->setCurrentIndex(1); ui->comboAxis->addItem(tr("Select reference...")); } @@ -287,17 +289,11 @@ void TaskPolarPatternParameters::onUpdateView(bool on) if (on) { // Do the same like in TaskDlgPolarPatternParameters::accept() but without doCommand PartDesign::PolarPattern* pcPolarPattern = static_cast(getObject()); + std::vector axes; + App::DocumentObject* obj; - std::string axis = getAxis(); - if (!axis.empty()) { - std::vector axes(1,axis); - if (axis == "N_Axis") - pcPolarPattern->Axis.setValue(getSketchObject(), axes); - else - pcPolarPattern->Axis.setValue(getSupportObject(), axes); - } else - pcPolarPattern->Axis.setValue(NULL); - + getAxis(obj, axes); + pcPolarPattern->Axis.setValue(obj,axes); pcPolarPattern->Reversed.setValue(getReverse()); pcPolarPattern->Angle.setValue(getAngle()); pcPolarPattern->Occurrences.setValue(getOccurrences()); @@ -306,13 +302,21 @@ void TaskPolarPatternParameters::onUpdateView(bool on) } } -const std::string TaskPolarPatternParameters::getAxis(void) const -{ - if (ui->comboAxis->currentIndex() == 0) - return "N_Axis"; - else if (ui->comboAxis->count() > 2 && ui->comboAxis->currentIndex() == 1) - return ui->comboAxis->currentText().toStdString(); - return std::string(""); +void TaskPolarPatternParameters::getAxis(App::DocumentObject*& obj, std::vector& sub) const +{ + obj = getSketchObject(); + sub = std::vector(1,""); + + if (ui->comboAxis->currentIndex() == 0) { + sub[0] = "N_Axis"; + } else if (ui->comboAxis->count() > 2 && ui->comboAxis->currentIndex() == 1) { + QStringList parts = ui->comboAxis->currentText().split(QChar::fromAscii(':')); + obj = getObject()->getDocument()->getObject(parts[0].toStdString().c_str()); + if (parts.size() > 1) + sub[0] = parts[1].toStdString(); + } else { + obj = NULL; + } } const bool TaskPolarPatternParameters::getReverse(void) const @@ -349,21 +353,12 @@ void TaskPolarPatternParameters::changeEvent(QEvent *e) void TaskPolarPatternParameters::apply() { std::string name = TransformedView->getObject()->getNameInDocument(); - std::string axis = getAxis(); - - if (!axis.empty()) { - App::DocumentObject* sketch = 0; - if (axis == "N_Axis") - sketch = getSketchObject(); - else - sketch = getSupportObject(); - - if (sketch) { - QString buf = QString::fromLatin1("(App.ActiveDocument.%1,[\"%2\"])"); - buf = buf.arg(QString::fromLatin1(sketch->getNameInDocument())); - buf = buf.arg(QString::fromLatin1(axis.c_str())); - Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Axis = %s", name.c_str(), buf.toStdString().c_str()); - } + std::vector axes; + App::DocumentObject* obj; + getAxis(obj, axes); + std::string axis = getPythonStr(obj, axes); + if (!axis.empty()) { + Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Axis = %s", name.c_str(), axis.c_str()); } else Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Axis = None", name.c_str()); Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Reversed = %u",name.c_str(),getReverse()); @@ -393,7 +388,6 @@ TaskDlgPolarPatternParameters::TaskDlgPolarPatternParameters(ViewProviderPolarPa bool TaskDlgPolarPatternParameters::accept() { try { - //Gui::Command::openCommand("PolarPattern changed"); // Handle Originals if (!TaskDlgTransformedParameters::accept()) return false; diff --git a/src/Mod/PartDesign/Gui/TaskPolarPatternParameters.cpp.orig b/src/Mod/PartDesign/Gui/TaskPolarPatternParameters.cpp.orig new file mode 100644 index 0000000000..085ed2d81c --- /dev/null +++ b/src/Mod/PartDesign/Gui/TaskPolarPatternParameters.cpp.orig @@ -0,0 +1,424 @@ +/****************************************************************************** + * Copyright (c)2012 Jan Rheinlaender * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ******************************************************************************/ + + +#include "PreCompiled.h" + +#ifndef _PreComp_ +# include +# include +#endif + +#include "ui_TaskPolarPatternParameters.h" +#include "TaskPolarPatternParameters.h" +#include "TaskMultiTransformParameters.h" +#include "Workbench.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace PartDesignGui; +using namespace Gui; + +/* TRANSLATOR PartDesignGui::TaskPolarPatternParameters */ + +TaskPolarPatternParameters::TaskPolarPatternParameters(ViewProviderTransformed *TransformedView,QWidget *parent) + : TaskTransformedParameters(TransformedView, parent) +{ + // we need a separate container widget to add all controls to + proxy = new QWidget(this); + ui = new Ui_TaskPolarPatternParameters(); + ui->setupUi(proxy); + QMetaObject::connectSlotsByName(this); + + this->groupLayout()->addWidget(proxy); + + ui->buttonOK->hide(); + ui->checkBoxUpdateView->setEnabled(true); + + referenceSelectionMode = false; + + blockUpdate = false; // Hack, sometimes it is NOT false although set to false in Transformed::Transformed()!! + setupUI(); +} + +TaskPolarPatternParameters::TaskPolarPatternParameters(TaskMultiTransformParameters *parentTask, QLayout *layout) + : TaskTransformedParameters(parentTask) +{ + proxy = new QWidget(parentTask); + ui = new Ui_TaskPolarPatternParameters(); + ui->setupUi(proxy); + connect(ui->buttonOK, SIGNAL(pressed()), + parentTask, SLOT(onSubTaskButtonOK())); + QMetaObject::connectSlotsByName(this); + + layout->addWidget(proxy); + + ui->buttonOK->setEnabled(true); + ui->labelOriginal->hide(); + ui->lineOriginal->hide(); + ui->checkBoxUpdateView->hide(); + + referenceSelectionMode = false; + + blockUpdate = false; // Hack, sometimes it is NOT false although set to false in Transformed::Transformed()!! + setupUI(); +} + +void TaskPolarPatternParameters::setupUI() +{ + updateViewTimer = new QTimer(this); + updateViewTimer->setSingleShot(true); + updateViewTimer->setInterval(getUpdateViewTimeout()); + + connect(updateViewTimer, SIGNAL(timeout()), + this, SLOT(onUpdateViewTimer())); + connect(ui->comboAxis, SIGNAL(activated(int)), + this, SLOT(onAxisChanged(int))); + connect(ui->checkReverse, SIGNAL(toggled(bool)), + this, SLOT(onCheckReverse(bool))); + connect(ui->polarAngle, SIGNAL(valueChanged(double)), + this, SLOT(onAngle(double))); + connect(ui->spinOccurrences, SIGNAL(valueChanged(uint)), + this, SLOT(onOccurrences(uint))); + connect(ui->checkBoxUpdateView, SIGNAL(toggled(bool)), + this, SLOT(onUpdateView(bool))); + + // Get the feature data + PartDesign::PolarPattern* pcPolarPattern = static_cast(getObject()); + std::vector originals = pcPolarPattern->Originals.getValues(); + + // Fill data into dialog elements + ui->lineOriginal->setEnabled(false); + for (std::vector::const_iterator i = originals.begin(); i != originals.end(); ++i) + { + if ((*i) != NULL) { // find the first valid original + ui->lineOriginal->setText(QString::fromLatin1((*i)->getNameInDocument())); + break; + } + } + // --------------------- + + ui->polarAngle->bind(pcPolarPattern->Angle); + ui->spinOccurrences->setMaximum(INT_MAX); + ui->spinOccurrences->bind(pcPolarPattern->Occurrences); + + ui->comboAxis->setEnabled(true); + ui->checkReverse->setEnabled(true); + ui->polarAngle->setEnabled(true); + ui->spinOccurrences->setEnabled(true); + updateUI(); +} + +void TaskPolarPatternParameters::updateUI() +{ + if (blockUpdate) + return; + blockUpdate = true; + + PartDesign::PolarPattern* pcPolarPattern = static_cast(getObject()); + + App::DocumentObject* axisFeature = pcPolarPattern->Axis.getValue(); + std::vector axes = pcPolarPattern->Axis.getSubValues(); + bool reverse = pcPolarPattern->Reversed.getValue(); + double angle = pcPolarPattern->Angle.getValue(); + unsigned occurrences = pcPolarPattern->Occurrences.getValue(); + + for (int i=ui->comboAxis->count()-1; i >= 1; i--) + ui->comboAxis->removeItem(i); + + if (axisFeature != NULL && !axes.empty()) { + if (axes.front() == "N_Axis") + ui->comboAxis->setCurrentIndex(0); +<<<<<<< 9c07d220e78d49c084d7ec2cec90f1df0572e044 + else if (axisFeature != NULL && !axes.empty()) { + ui->comboAxis->addItem(QString::fromLatin1(axes.front().c_str())); +======= + else { + ui->comboAxis->addItem(getRefStr(axisFeature, axes)); +>>>>>>> Allow datum lines and planes for Transformed features' references + ui->comboAxis->setCurrentIndex(1); + } + } else { + // Error message? + } + + if (referenceSelectionMode) { + ui->comboAxis->addItem(tr("Select an edge or datum line")); + ui->comboAxis->setCurrentIndex(ui->comboAxis->count() - 1); + } else + ui->comboAxis->addItem(tr("Select reference...")); + + // Note: These three lines would trigger onLength(), on Occurrences() and another updateUI() if we + // didn't check for blockUpdate + ui->checkReverse->setChecked(reverse); + ui->polarAngle->setValue(angle); + ui->spinOccurrences->setValue(occurrences); + + blockUpdate = false; +} + +void TaskPolarPatternParameters::onUpdateViewTimer() +{ + recomputeFeature(); +} + +void TaskPolarPatternParameters::kickUpdateViewTimer() const +{ + updateViewTimer->start(); +} + +void TaskPolarPatternParameters::onSelectionChanged(const Gui::SelectionChanges& msg) +{ + if (msg.Type == Gui::SelectionChanges::AddSelection) { + + if (strcmp(msg.pDocName, getObject()->getDocument()->getName()) != 0) + return; + + if (originalSelected(msg)) { +<<<<<<< 9c07d220e78d49c084d7ec2cec90f1df0572e044 + ui->lineOriginal->setText(QString::fromLatin1(msg.pObjectName)); + } else if (referenceSelectionMode && + (subName.size() > 4 && subName.substr(0,4) == "Edge")) { + + if (strcmp(msg.pObjectName, getSupportObject()->getNameInDocument()) != 0) + return; + +======= + ui->lineOriginal->setText(QString::fromAscii(msg.pObjectName)); + } else if (referenceSelectionMode) { + // Note: ReferenceSelection has already checked the selection for validity +>>>>>>> Allow datum lines and planes for Transformed features' references + exitSelectionMode(); + if (!blockUpdate) { + std::vector axes; + App::DocumentObject* selObj; + getReferencedSelection(msg, selObj, axes); + PartDesign::PolarPattern* pcPolarPattern = static_cast(getObject()); + pcPolarPattern->Axis.setValue(selObj, axes); + + recomputeFeature(); + updateUI(); + } + else { + for (int i=ui->comboAxis->count()-1; i >= 1; i--) + ui->comboAxis->removeItem(i); + +<<<<<<< 9c07d220e78d49c084d7ec2cec90f1df0572e044 + ui->comboAxis->addItem(QString::fromLatin1(subName.c_str())); +======= + std::vector axes; + App::DocumentObject* selObj; + getReferencedSelection(msg, selObj, axes); + ui->comboAxis->addItem(getRefStr(selObj, axes)); +>>>>>>> Allow datum lines and planes for Transformed features' references + ui->comboAxis->setCurrentIndex(1); + ui->comboAxis->addItem(tr("Select reference...")); + } + } + } +} + +void TaskPolarPatternParameters::onCheckReverse(const bool on) { + if (blockUpdate) + return; + PartDesign::PolarPattern* pcPolarPattern = static_cast(getObject()); + pcPolarPattern->Reversed.setValue(on); + + exitSelectionMode(); + kickUpdateViewTimer(); +} + +void TaskPolarPatternParameters::onAngle(const double a) { + if (blockUpdate) + return; + PartDesign::PolarPattern* pcPolarPattern = static_cast(getObject()); + pcPolarPattern->Angle.setValue(a); + + exitSelectionMode(); + kickUpdateViewTimer(); +} + +void TaskPolarPatternParameters::onOccurrences(const uint n) { + if (blockUpdate) + return; + PartDesign::PolarPattern* pcPolarPattern = static_cast(getObject()); + pcPolarPattern->Occurrences.setValue(n); + + exitSelectionMode(); + kickUpdateViewTimer(); +} + +void TaskPolarPatternParameters::onAxisChanged(int num) { + if (blockUpdate) + return; + PartDesign::PolarPattern* pcPolarPattern = static_cast(getObject()); + + if (num == 0) { + pcPolarPattern->Axis.setValue(getSketchObject(), std::vector(1,"N_Axis")); + exitSelectionMode(); + } + else if (num == ui->comboAxis->count() - 1) { + // enter reference selection mode + hideObject(); + showOriginals(); + referenceSelectionMode = true; + Gui::Selection().clearSelection(); + addReferenceSelectionGate(true, false); + } + else if (num == 1) + exitSelectionMode(); + + kickUpdateViewTimer(); +} + +void TaskPolarPatternParameters::onUpdateView(bool on) +{ + blockUpdate = !on; + if (on) { + // Do the same like in TaskDlgPolarPatternParameters::accept() but without doCommand + PartDesign::PolarPattern* pcPolarPattern = static_cast(getObject()); + std::vector axes; + App::DocumentObject* obj; + + getAxis(obj, axes); + pcPolarPattern->Axis.setValue(obj,axes); + pcPolarPattern->Reversed.setValue(getReverse()); + pcPolarPattern->Angle.setValue(getAngle()); + pcPolarPattern->Occurrences.setValue(getOccurrences()); + + recomputeFeature(); + } +} + +void TaskPolarPatternParameters::getAxis(App::DocumentObject*& obj, std::vector& sub) const +{ + obj = getSketchObject(); + sub = std::vector(1,""); + + if (ui->comboAxis->currentIndex() == 0) { + sub[0] = "N_Axis"; + } else if (ui->comboAxis->count() > 2 && ui->comboAxis->currentIndex() == 1) { + QStringList parts = ui->comboAxis->currentText().split(QChar::fromAscii(':')); + obj = getObject()->getDocument()->getObject(parts[0].toStdString().c_str()); + if (parts.size() > 1) + sub[0] = parts[1].toStdString(); + } else { + obj = NULL; + } +} + +const bool TaskPolarPatternParameters::getReverse(void) const +{ + return ui->checkReverse->isChecked(); +} + +const double TaskPolarPatternParameters::getAngle(void) const +{ + return ui->polarAngle->value().getValue(); +} + +const unsigned TaskPolarPatternParameters::getOccurrences(void) const +{ + return ui->spinOccurrences->value(); +} + + +TaskPolarPatternParameters::~TaskPolarPatternParameters() +{ + delete ui; + if (proxy) + delete proxy; +} + +void TaskPolarPatternParameters::changeEvent(QEvent *e) +{ + TaskBox::changeEvent(e); + if (e->type() == QEvent::LanguageChange) { + ui->retranslateUi(proxy); + } +} + +void TaskPolarPatternParameters::apply() +{ + std::string name = TransformedView->getObject()->getNameInDocument(); + std::vector axes; + App::DocumentObject* obj; + getAxis(obj, axes); + std::string axis = getPythonStr(obj, axes); + if (!axis.empty()) { + Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Axis = %s", name.c_str(), axis.c_str()); + } else + Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Axis = None", name.c_str()); + Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Reversed = %u",name.c_str(),getReverse()); + ui->polarAngle->apply(); + ui->spinOccurrences->apply(); + Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.recompute()"); + if (!TransformedView->getObject()->isValid()) + throw Base::Exception(TransformedView->getObject()->getStatusString()); + Gui::Command::doCommand(Gui::Command::Gui,"Gui.activeDocument().resetEdit()"); + Gui::Command::commitCommand(); +} + +//************************************************************************** +//************************************************************************** +// TaskDialog +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +TaskDlgPolarPatternParameters::TaskDlgPolarPatternParameters(ViewProviderPolarPattern *PolarPatternView) + : TaskDlgTransformedParameters(PolarPatternView) +{ + parameter = new TaskPolarPatternParameters(PolarPatternView); + + Content.push_back(parameter); +} +//==== calls from the TaskView =============================================================== + +bool TaskDlgPolarPatternParameters::accept() +{ + try { + // Handle Originals + if (!TaskDlgTransformedParameters::accept()) + return false; + + parameter->apply(); + } + catch (const Base::Exception& e) { + QMessageBox::warning(parameter, tr("Input error"), QString::fromLatin1(e.what())); + return false; + } + + return true; +} + +#include "moc_TaskPolarPatternParameters.cpp" diff --git a/src/Mod/PartDesign/Gui/TaskPolarPatternParameters.h b/src/Mod/PartDesign/Gui/TaskPolarPatternParameters.h index 442a3dcafe..531105cbb2 100644 --- a/src/Mod/PartDesign/Gui/TaskPolarPatternParameters.h +++ b/src/Mod/PartDesign/Gui/TaskPolarPatternParameters.h @@ -69,8 +69,9 @@ private Q_SLOTS: protected: virtual void changeEvent(QEvent *e); virtual void onSelectionChanged(const Gui::SelectionChanges& msg); + void getAxis(App::DocumentObject*& obj, std::vector& sub) const; const std::string getStdAxis(void) const; - const std::string getAxis(void) const; + //const std::string getAxis(void) const; const bool getReverse(void) const; const double getAngle(void) const; const unsigned getOccurrences(void) const; diff --git a/src/Mod/PartDesign/Gui/TaskTransformedParameters.cpp b/src/Mod/PartDesign/Gui/TaskTransformedParameters.cpp index 6615ee0573..ce5f7f5a81 100644 --- a/src/Mod/PartDesign/Gui/TaskTransformedParameters.cpp +++ b/src/Mod/PartDesign/Gui/TaskTransformedParameters.cpp @@ -98,7 +98,7 @@ const bool TaskTransformedParameters::originalSelected(const Gui::SelectionChang { if (msg.Type == Gui::SelectionChanges::AddSelection && originalSelectionMode) { - if (strcmp(msg.pDocName, getObject()->getDocument()->getName()) != 0) + if ((msg.pDocName, getObject()->getDocument()->getName()) != 0) return false; PartDesign::Transformed* pcTransformed = getObject(); @@ -228,6 +228,46 @@ void TaskTransformedParameters::addReferenceSelectionGate(bool edge, bool face) Gui::Selection().addSelectionGate(new ReferenceSelection(getSupportObject(), edge, face, true)); } +void TaskTransformedParameters::getReferencedSelection(const Gui::SelectionChanges& msg, + App::DocumentObject*& selObj, std::vector& selSub) +{ + PartDesign::Transformed* pcTransformed = static_cast(getObject()); + selObj = pcTransformed->getDocument()->getObject(msg.pObjectName); + if (selObj == pcTransformed) + return; + std::string subname = msg.pSubName; + + // Remove subname for planes and datum features + if (PartDesign::Feature::isDatum(selObj)) { + subname = ""; + } + + selSub = std::vector(1,subname); +} + +const QString TaskTransformedParameters::getRefStr(const App::DocumentObject* obj, const std::vector& sub) +{ + if (obj == NULL) + return QString::fromAscii(""); + + if (PartDesign::Feature::isDatum(obj)) + return QString::fromAscii(obj->getNameInDocument()); + else + return QString::fromAscii(obj->getNameInDocument()) + QString::fromAscii(":") + + QString::fromAscii(sub.front().c_str()); +} + +const std::string TaskTransformedParameters::getPythonStr(const App::DocumentObject* obj, const std::vector& sub) +{ + if (obj == NULL) + return ""; + + if (PartDesign::Feature::isDatum(obj)) + return std::string("(App.ActiveDocument.") + obj->getNameInDocument() + ", [\"\"])"; + else + return std::string("(App.ActiveDocument.") + obj->getNameInDocument() + ", [\"" + sub.front() + "\"])"; +} + //************************************************************************** //************************************************************************** diff --git a/src/Mod/PartDesign/Gui/TaskTransformedParameters.h b/src/Mod/PartDesign/Gui/TaskTransformedParameters.h index c497665484..30209268ad 100644 --- a/src/Mod/PartDesign/Gui/TaskTransformedParameters.h +++ b/src/Mod/PartDesign/Gui/TaskTransformedParameters.h @@ -64,6 +64,9 @@ public: /// Get the sketch object of the first original either of the object associated with this feature or with the parent feature (MultiTransform mode) App::DocumentObject* getSketchObject() const; + /// Return reference as string for python (format (, [""]) ) + const std::string getPythonStr(const App::DocumentObject* selObj, const std::vector& selSub); + void exitSelectionMode(); virtual void apply() = 0; @@ -87,6 +90,12 @@ protected: void showOriginals(); void addReferenceSelectionGate(bool edge, bool face); + /// Extract reference from Selection (convenience method) + void getReferencedSelection(const Gui::SelectionChanges& msg, + App::DocumentObject*& selObj, std::vector& selSub); + /// Return reference as string for UI elements (format : + const QString getRefStr(const App::DocumentObject* selObj, const std::vector& selSub); + bool isViewUpdated() const; int getUpdateViewTimeout() const; @@ -106,7 +115,7 @@ protected: /// Flag indicating whether this object is a container for MultiTransform bool insideMultiTransform; /// Lock updateUI(), applying changes to the underlying feature and calling recomputeFeature() - bool blockUpdate; + bool blockUpdate; }; /// simulation dialog for the TaskView