diff --git a/src/Mod/Part/Gui/DlgPrimitives.cpp b/src/Mod/Part/Gui/DlgPrimitives.cpp
index 9a42a4ae9e..f8d7109002 100644
--- a/src/Mod/Part/Gui/DlgPrimitives.cpp
+++ b/src/Mod/Part/Gui/DlgPrimitives.cpp
@@ -39,6 +39,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -48,6 +49,7 @@
#include
#include
#include
+#include
#include
#include "DlgPrimitives.h"
@@ -56,6 +58,8 @@ using namespace PartGui;
namespace PartGui {
+const char* ObjectNameSave;
+
const char* gce_ErrorStatusText(gce_ErrorType et)
{
switch (et)
@@ -180,13 +184,49 @@ private:
/* TRANSLATOR PartGui::DlgPrimitives */
-DlgPrimitives::DlgPrimitives(QWidget* parent)
+DlgPrimitives::DlgPrimitives(QWidget* parent, PrimitiveType type, bool edit, const char* ObjectName)
: QWidget(parent)
{
ui.setupUi(this);
Gui::Command::doCommand(Gui::Command::Doc, "from FreeCAD import Base");
Gui::Command::doCommand(Gui::Command::Doc, "import Part,PartGui");
+ ui.comboBox1->setCurrentIndex(type);
+ ui.widgetStack2->setCurrentIndex(type);
+
+ // fill the dialog with data if the primitives already exists
+ if (edit) {
+ // if existing, the primitive type can not be changed by the user
+ ui.comboBox1->setDisabled(edit);
+ // get the primitives object
+ Gui::Document* doc = Gui::Application::Instance->activeDocument();
+ if (!doc)
+ return;
+ auto docObj = doc->getDocument()->getObject(ObjectName);
+
+ // read values from the properties
+ if (type == PrimitiveType::Helix)
+ {
+ auto Property = docObj->getPropertyByName("Pitch");
+ auto value = static_cast(Property);
+ ui.helixPitch->setValue(value->getQuantityValue());
+ Property = docObj->getPropertyByName("Height");
+ value = static_cast(Property);
+ ui.helixHeight->setValue(value->getQuantityValue());
+ Property = docObj->getPropertyByName("Radius");
+ value = static_cast(Property);
+ ui.helixRadius->setValue(value->getQuantityValue());
+ Property = docObj->getPropertyByName("Angle");
+ value = static_cast(Property);
+ ui.helixAngle->setValue(value->getQuantityValue());
+ Property = docObj->getPropertyByName("LocalCoord");
+ auto HandedIndex = static_cast(Property);
+ ui.helixLocalCS->setCurrentIndex(HandedIndex->getValue());
+
+ // ToDo: connect signal if there is a preview of primitives available
+ }
+ }
+
// set limits
//
// plane
@@ -682,15 +722,87 @@ void DlgPrimitives::createPrimitive(const QString& placement)
}
}
+void DlgPrimitives::accept(const QString& placement)
+{
+ QString command;
+
+ // get the current object
+ Gui::Document* doc = Gui::Application::Instance->activeDocument();
+ if (!doc)
+ return;
+ auto docObj = doc->getDocument()->getObject(ObjectNameSave);
+ auto ObjectName = docObj->getNameInDocument();
+
+ // the combox with the primitive type is fixed
+ // therefore by reading its state we know what we need to change
+ if (ui.comboBox1->currentIndex() == 9) { // helix
+
+ command = QString::fromLatin1(
+ "App.ActiveDocument.%1.Pitch=%2\n"
+ "App.ActiveDocument.%1.Height=%3\n"
+ "App.ActiveDocument.%1.Radius=%4\n"
+ "App.ActiveDocument.%1.Angle=%5\n"
+ "App.ActiveDocument.%1.LocalCoord=%6\n"
+ "App.ActiveDocument.%1.Placement=%7\n"
+ "App.ActiveDocument.recompute()\n")
+ .arg(QString::fromLatin1(ObjectName))
+ .arg(ui.helixPitch->value().getValue(), 0, 'f', Base::UnitsApi::getDecimals())
+ .arg(ui.helixHeight->value().getValue(), 0, 'f', Base::UnitsApi::getDecimals())
+ .arg(ui.helixRadius->value().getValue(), 0, 'f', Base::UnitsApi::getDecimals())
+ .arg(ui.helixAngle->value().getValue(), 0, 'f', Base::UnitsApi::getDecimals())
+ .arg(ui.helixLocalCS->currentIndex())
+ .arg(placement);
+ }
+
+ // store command for undo
+ doc->openCommand(command.toUtf8());
+ // execute command
+ Gui::Command::runCommand(Gui::Command::App, command.toLatin1());
+ // commit undo command
+ doc->commitCommand();
+}
+
// ----------------------------------------------
/* TRANSLATOR PartGui::Location */
-Location::Location(QWidget* parent)
+Location::Location(QWidget* parent, bool edit, const char* ObjectName)
{
Q_UNUSED(parent);
mode = 0;
ui.setupUi(this);
+
+ ui.XPositionQSB->setUnit(Base::Unit::Length);
+ ui.YPositionQSB->setUnit(Base::Unit::Length);
+ ui.ZPositionQSB->setUnit(Base::Unit::Length);
+ ui.AngleQSB->setUnit(Base::Unit::Angle);
+
+ // fill location widget if object already exists
+ if (edit) {
+ // get the primitives object
+ Gui::Document* doc = Gui::Application::Instance->activeDocument();
+ if (!doc)
+ return;
+ auto docObj = doc->getDocument()->getObject(ObjectName);
+ // get the placement values
+ auto Property = docObj->getPropertyByName("Placement");
+ auto placement = static_cast(Property);
+
+ auto position = placement->getValue().getPosition();
+ ui.XPositionQSB->setValue(position.x);
+ ui.YPositionQSB->setValue(position.y);
+ ui.ZPositionQSB->setValue(position.z);
+
+ double rotationAngle;
+ Base::Vector3d rotationAxes;
+ auto rotation = placement->getValue().getRotation();
+ rotation.getRawValue(rotationAxes, rotationAngle);
+ ui.XDirectionEdit->setValue(rotationAxes.x);
+ ui.YDirectionEdit->setValue(rotationAxes.y);
+ ui.ZDirectionEdit->setValue(rotationAxes.z);
+ // the angle is in this format: 180° = PI, thus transform it to deg
+ ui.AngleQSB->setValue(rotationAngle*180/M_PI);
+ }
}
Location::~Location()
@@ -746,8 +858,12 @@ void Location::pickCallback(void * ud, SoEventCallback * n)
SbVec3f pnt = point->getPoint();
SbVec3f nor = point->getNormal();
Location* dlg = reinterpret_cast(ud);
- dlg->ui.loc->setPosition(Base::Vector3d(pnt[0],pnt[1],pnt[2]));
- dlg->ui.loc->setDirection(Base::Vector3d(nor[0],nor[1],nor[2]));
+ dlg->ui.XPositionQSB->setValue(pnt[0]);
+ dlg->ui.YPositionQSB->setValue(pnt[1]);
+ dlg->ui.ZPositionQSB->setValue(pnt[2]);
+ dlg->ui.XDirectionEdit->setValue(nor[0]);
+ dlg->ui.YDirectionEdit->setValue(nor[1]);
+ dlg->ui.ZDirectionEdit->setValue(nor[2]);
n->setHandled();
}
}
@@ -769,59 +885,28 @@ void Location::pickCallback(void * ud, SoEventCallback * n)
QString Location::toPlacement() const
{
- Base::Vector3d d = ui.loc->getDirection();
- gp_Dir dir = gp_Dir(d.x,d.y,d.z);
- gp_Pnt pnt = gp_Pnt(0.0,0.0,0.0);
- gp_Ax3 ax3;
+ // create a command to set the position and angle of the primitive object
- double cosNX = dir.Dot(gp::DX());
- double cosNY = dir.Dot(gp::DY());
- double cosNZ = dir.Dot(gp::DZ());
- std::vector cosXYZ;
- cosXYZ.push_back(fabs(cosNX));
- cosXYZ.push_back(fabs(cosNY));
- cosXYZ.push_back(fabs(cosNZ));
+ Base::Vector3d rot;
+ rot.x = ui.XDirectionEdit->value();
+ rot.y = ui.YDirectionEdit->value();
+ rot.z = ui.ZDirectionEdit->value();
- int pos = std::max_element(cosXYZ.begin(), cosXYZ.end()) - cosXYZ.begin();
+ double angle = ui.AngleQSB->rawValue();
- // +X/-X
- if (pos == 0) {
- if (cosNX > 0)
- ax3 = gp_Ax3(pnt, dir, gp_Dir(0,1,0));
- else
- ax3 = gp_Ax3(pnt, dir, gp_Dir(0,-1,0));
- }
- // +Y/-Y
- else if (pos == 1) {
- if (cosNY > 0)
- ax3 = gp_Ax3(pnt, dir, gp_Dir(0,0,1));
- else
- ax3 = gp_Ax3(pnt, dir, gp_Dir(0,0,-1));
- }
- // +Z/-Z
- else {
- ax3 = gp_Ax3(pnt, dir, gp_Dir(1,0,0));
- }
+ Base::Vector3d loc;
+ loc.x = ui.XPositionQSB->rawValue();
+ loc.y = ui.YPositionQSB->rawValue();
+ loc.z = ui.ZPositionQSB->rawValue();
- gp_Trsf Trf;
- Trf.SetTransformation(ax3);
- Trf.Invert();
-
- gp_XYZ theAxis(0,0,1);
- Standard_Real theAngle = 0.0;
- Trf.GetRotation(theAxis,theAngle);
-
- Base::Rotation rot(Base::convertTo(theAxis), theAngle);
- Base::Vector3d loc = ui.loc->getPosition();
-
- return QString::fromLatin1("Base.Placement(Base.Vector(%1,%2,%3),Base.Rotation(%4,%5,%6,%7))")
- .arg(loc.x,0,'f',Base::UnitsApi::getDecimals())
- .arg(loc.y,0,'f',Base::UnitsApi::getDecimals())
- .arg(loc.z,0,'f',Base::UnitsApi::getDecimals())
- .arg(rot[0],0,'f',Base::UnitsApi::getDecimals())
- .arg(rot[1],0,'f',Base::UnitsApi::getDecimals())
- .arg(rot[2],0,'f',Base::UnitsApi::getDecimals())
- .arg(rot[3],0,'f',Base::UnitsApi::getDecimals());
+ return QString::fromLatin1("App.Placement(App.Vector(%1,%2,%3),App.Rotation(App.Vector(%4,%5,%6),%7))")
+ .arg(loc.x, 0, 'f', Base::UnitsApi::getDecimals())
+ .arg(loc.y, 0, 'f', Base::UnitsApi::getDecimals())
+ .arg(loc.z, 0, 'f', Base::UnitsApi::getDecimals())
+ .arg(rot.x, 0, 'f', Base::UnitsApi::getDecimals())
+ .arg(rot.y, 0, 'f', Base::UnitsApi::getDecimals())
+ .arg(rot.z, 0, 'f', Base::UnitsApi::getDecimals())
+ .arg(angle, 0, 'f', Base::UnitsApi::getDecimals());
}
// ----------------------------------------------
@@ -832,14 +917,13 @@ TaskPrimitives::TaskPrimitives()
{
Gui::TaskView::TaskBox* taskbox;
widget = new DlgPrimitives();
- taskbox = new Gui::TaskView::TaskBox(QPixmap(), widget->windowTitle(),true, 0);
+ taskbox = new Gui::TaskView::TaskBox(QPixmap(), widget->windowTitle(), true, 0);
taskbox->groupLayout()->addWidget(widget);
Content.push_back(taskbox);
location = new Location();
- taskbox = new Gui::TaskView::TaskBox(QPixmap(), location->windowTitle(),true, 0);
+ taskbox = new Gui::TaskView::TaskBox(QPixmap(), location->windowTitle() ,true, 0);
taskbox->groupLayout()->addWidget(location);
- taskbox->hideGroupBox();
Content.push_back(taskbox);
}
@@ -871,4 +955,57 @@ bool TaskPrimitives::reject()
return true;
}
+// ----------------------------------------------
+
+/* TRANSLATOR PartGui::TaskPrimitivesEdit */
+
+TaskPrimitivesEdit::TaskPrimitivesEdit(DlgPrimitives::PrimitiveType type, const char* ObjectName)
+{
+ // save object name to be able to access it in accept() since if there are e.g. 3 helices
+ // the last one would be the active object, no matter that one is editing the first one
+ ObjectNameSave = ObjectName;
+ // create and show dialog for the primitives
+ Gui::TaskView::TaskBox* taskbox;
+ widget = new DlgPrimitives(0, type, true, ObjectName);
+ taskbox = new Gui::TaskView::TaskBox(QPixmap(), widget->windowTitle(), true, 0);
+ taskbox->groupLayout()->addWidget(widget);
+ Content.push_back(taskbox);
+
+ // create and show dialog for the location
+ location = new Location(0, true, ObjectName);
+ taskbox = new Gui::TaskView::TaskBox(QPixmap(), location->windowTitle(), true, 0);
+ taskbox->groupLayout()->addWidget(location);
+ Content.push_back(taskbox);
+}
+
+TaskPrimitivesEdit::~TaskPrimitivesEdit()
+{
+ // automatically deleted in the sub-class
+}
+
+QDialogButtonBox::StandardButtons TaskPrimitivesEdit::getStandardButtons() const
+{
+ return QDialogButtonBox::Close |
+ QDialogButtonBox::Ok;
+}
+
+void TaskPrimitivesEdit::modifyStandardButtons(QDialogButtonBox* box)
+{
+ QPushButton* btn = box->button(QDialogButtonBox::Ok);
+ btn->setText(QApplication::translate("PartGui::DlgPrimitives", "&OK"));
+}
+
+bool TaskPrimitivesEdit::accept()
+{
+ widget->accept(location->toPlacement());
+ Gui::Command::doCommand(Gui::Command::Gui, "Gui.activeDocument().resetEdit()");
+ return true;
+}
+
+bool TaskPrimitivesEdit::reject()
+{
+ Gui::Command::doCommand(Gui::Command::Gui, "Gui.activeDocument().resetEdit()");
+ return true;
+}
+
#include "moc_DlgPrimitives.cpp"
diff --git a/src/Mod/Part/Gui/DlgPrimitives.h b/src/Mod/Part/Gui/DlgPrimitives.h
index 14a1fd0af5..4bda9c260f 100644
--- a/src/Mod/Part/Gui/DlgPrimitives.h
+++ b/src/Mod/Part/Gui/DlgPrimitives.h
@@ -60,9 +60,16 @@ class DlgPrimitives : public QWidget
Q_OBJECT
public:
- DlgPrimitives(QWidget* parent = 0);
+ enum PrimitiveType {
+ Plane, Box, Cylinder, Cone, Sphere, Ellipsoid, Torus, Prism, Wedge,
+ Helix, Spiral, Circle, Ellipse, Point, Line, RegPolygon
+ };
+
+ DlgPrimitives(QWidget* parent = 0, PrimitiveType type = PrimitiveType::Plane,
+ bool edit = false, const char* ObjectName = "");
~DlgPrimitives();
void createPrimitive(const QString&);
+ void accept(const QString&);
private Q_SLOTS:
void on_buttonCircleFromThreePoints_clicked();
@@ -80,7 +87,7 @@ class Location : public QWidget
Q_OBJECT
public:
- Location(QWidget* parent = 0);
+ Location(QWidget* parent = 0, bool edit = false, const char* ObjectName = "");
~Location();
QString toPlacement() const;
@@ -105,7 +112,6 @@ public:
public:
bool accept();
bool reject();
-
QDialogButtonBox::StandardButtons getStandardButtons() const;
void modifyStandardButtons(QDialogButtonBox*);
@@ -114,6 +120,25 @@ private:
Location* location;
};
+class TaskPrimitivesEdit : public Gui::TaskView::TaskDialog
+{
+ Q_OBJECT
+
+public:
+ TaskPrimitivesEdit(DlgPrimitives::PrimitiveType type, const char* ObjectName);
+ ~TaskPrimitivesEdit();
+
+public:
+ bool accept();
+ bool reject();
+ QDialogButtonBox::StandardButtons getStandardButtons() const;
+ void modifyStandardButtons(QDialogButtonBox*);
+
+private:
+ DlgPrimitives* widget;
+ Location* location;
+};
+
} // namespace PartGui
#endif // PARTGUI_DLGPRIMITIVES_H
diff --git a/src/Mod/Part/Gui/Location.ui b/src/Mod/Part/Gui/Location.ui
index 69f22d4dd1..ce1b089399 100644
--- a/src/Mod/Part/Gui/Location.ui
+++ b/src/Mod/Part/Gui/Location.ui
@@ -6,8 +6,8 @@
0
0
- 209
- 205
+ 280
+ 307
@@ -16,52 +16,229 @@
true
-
- -
-
+
+
-
+
+
+
+ 0
+ 0
+
+
Position
-
-
-
- -
-
+
-
-
-
- Qt::Horizontal
+
+
+ X
-
-
- 40
- 20
-
-
-
+
-
-
+
+
+
+
+
+
+
+
+ -
+
+
-
+
- 3D View
+ Y
+
+
+
+ -
+
+
+
-
-
-
- Qt::Vertical
+
+
-
+
+
+ Z
+
+
+
+ -
+
+
+
+
+
+
+
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ Rotation
+
+
+
-
+
+
+ true
-
-
- 20
- 40
-
+
+ Use custom vector for pad direction otherwise
+the sketch plane's normal vector will be used
-
+
+ Rotation axis direction
+
+
+ false
+
+
+
-
+
+
-
+
+
+ x
+
+
+
+ -
+
+
+ x-component of direction vector
+
+
+ false
+
+
+ -100.000000000000000
+
+
+ 100.000000000000000
+
+
+ 0.100000000000000
+
+
+
+
+
+
+
+
+ -
+
+
-
+
+
+ y
+
+
+
+ -
+
+
+ y-component of direction vector
+
+
+ false
+
+
+ -100.000000000000000
+
+
+ 100.000000000000000
+
+
+ 0.100000000000000
+
+
+
+
+
+
+
+
+ -
+
+
-
+
+
+ z
+
+
+
+ -
+
+
+ z-component of direction vector
+
+
+ false
+
+
+ -100.000000000000000
+
+
+ 100.000000000000000
+
+
+ 0.100000000000000
+
+
+ 1.000000000000000
+
+
+
+
+
+
+
+
+
+
+
+ -
+
+
-
+
+
+ Angle
+
+
+
+ -
+
+
+
+
+
+ 5.000000000000000
+
+
+
+
@@ -71,9 +248,14 @@
- Gui::LocationWidget
+ Gui::QuantitySpinBox
QWidget
-
+
+
+
+ Gui::DoubleSpinBox
+ QDoubleSpinBox
+
diff --git a/src/Mod/Part/Gui/ViewProviderHelixParametric.cpp b/src/Mod/Part/Gui/ViewProviderHelixParametric.cpp
index ff39b7e10e..14678a1400 100644
--- a/src/Mod/Part/Gui/ViewProviderHelixParametric.cpp
+++ b/src/Mod/Part/Gui/ViewProviderHelixParametric.cpp
@@ -27,6 +27,9 @@
# include
#endif
+#include
+#include
+#include "DlgPrimitives.h"
#include "ViewProviderHelixParametric.h"
using namespace PartGui;
@@ -55,6 +58,46 @@ std::vector ViewProviderHelixParametric::getDisplayModes(void) cons
return StrList;
}
+void ViewProviderHelixParametric::setupContextMenu(QMenu* menu, QObject* receiver, const char* member)
+{
+ QAction* act;
+ act = menu->addAction(QObject::tr("Edit helix"), receiver, member);
+ act->setData(QVariant((int)ViewProvider::Default));
+ ViewProviderSpline::setupContextMenu(menu, receiver, member);
+}
+
+void ViewProviderHelixParametric::updateData(const App::Property* prop)
+{
+ PartGui::ViewProviderSpline::updateData(prop);
+}
+
+bool ViewProviderHelixParametric::setEdit(int ModNum)
+{
+ if (ModNum == ViewProvider::Default) {
+ if (Gui::Control().activeDialog())
+ return false;
+ auto ObjectName = getObject()->getNameInDocument();
+ PartGui::TaskPrimitivesEdit* dlg
+ = new PartGui::TaskPrimitivesEdit(PartGui::DlgPrimitives::PrimitiveType::Helix, ObjectName);
+ Gui::Control().showDialog(dlg);
+ return true;
+ }
+ else {
+ ViewProviderSpline::setEdit(ModNum);
+ return true;
+ }
+}
+
+void ViewProviderHelixParametric::unsetEdit(int ModNum)
+{
+ if (ModNum == ViewProvider::Default) {
+ Gui::Control().closeDialog();
+ }
+ else {
+ ViewProviderSpline::unsetEdit(ModNum);
+ }
+}
+
// ------------------------------------------------------------------
PROPERTY_SOURCE(PartGui::ViewProviderSpiralParametric, PartGui::ViewProviderSpline)
diff --git a/src/Mod/Part/Gui/ViewProviderHelixParametric.h b/src/Mod/Part/Gui/ViewProviderHelixParametric.h
index bb868c7330..bed55bce3b 100644
--- a/src/Mod/Part/Gui/ViewProviderHelixParametric.h
+++ b/src/Mod/Part/Gui/ViewProviderHelixParametric.h
@@ -39,6 +39,13 @@ public:
/// destructor
virtual ~ViewProviderHelixParametric();
std::vector getDisplayModes(void) const;
+ void setupContextMenu(QMenu*, QObject*, const char*);
+
+protected:
+ void updateData(const App::Property*);
+ bool setEdit(int ModNum);
+ void unsetEdit(int ModNum);
+
};
class PartGuiExport ViewProviderSpiralParametric : public ViewProviderSpline