diff --git a/src/Mod/PartDesign/App/AppPartDesign.cpp b/src/Mod/PartDesign/App/AppPartDesign.cpp index dbd6b0dbd..0922ad5ea 100644 --- a/src/Mod/PartDesign/App/AppPartDesign.cpp +++ b/src/Mod/PartDesign/App/AppPartDesign.cpp @@ -49,6 +49,7 @@ #include "FeatureScaled.h" #include "FeatureMultiTransform.h" #include "FeatureHole.h" +#include "DatumFeature.h" namespace PartDesign { extern PyObject* initModule(); @@ -95,5 +96,9 @@ PyMODINIT_FUNC init_PartDesign() PartDesign::Revolution ::init(); PartDesign::Groove ::init(); PartDesign::Chamfer ::init(); - PartDesign::Draft ::init(); + PartDesign::Draft ::init(); + PartDesign::Datum ::init(); + PartDesign::Plane ::init(); + PartDesign::Line ::init(); + PartDesign::Point ::init(); } diff --git a/src/Mod/PartDesign/App/AppPartDesign.cpp.orig b/src/Mod/PartDesign/App/AppPartDesign.cpp.orig new file mode 100644 index 000000000..b18162c07 --- /dev/null +++ b/src/Mod/PartDesign/App/AppPartDesign.cpp.orig @@ -0,0 +1,113 @@ +/*************************************************************************** + * Copyright (c) 2008 Jürgen Riegel (juergen.riegel@web.de) * + * * + * 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 +#include + +#include "FeaturePad.h" +#include "FeatureSolid.h" +#include "FeaturePocket.h" +#include "FeatureFillet.h" +#include "FeatureSketchBased.h" +#include "FeatureRevolution.h" +#include "FeatureGroove.h" +#include "Body.h" +#include "FeatureDressUp.h" +#include "FeatureChamfer.h" +#include "FeatureDraft.h" +#include "FeatureSubtractive.h" +#include "FeatureAdditive.h" +#include "FeatureTransformed.h" +#include "FeatureMirrored.h" +#include "FeatureLinearPattern.h" +#include "FeaturePolarPattern.h" +#include "FeatureScaled.h" +#include "FeatureMultiTransform.h" +#include "FeatureHole.h" +#include "DatumFeature.h" + +extern struct PyMethodDef PartDesign_methods[]; + +PyDoc_STRVAR(module_PartDesign_doc, +"This module is the PartDesign module."); + + +/* Python entry */ +extern "C" { +void PartDesignExport init_PartDesign() +{ + // load dependent module + try { + Base::Interpreter().runString("import Part"); + Base::Interpreter().runString("import Sketcher"); + } + catch(const Base::Exception& e) { + PyErr_SetString(PyExc_ImportError, e.what()); + return; + } + Py_InitModule3("_PartDesign", PartDesign_methods, module_PartDesign_doc); /* mod name, table ptr */ + Base::Console().Log("Loading PartDesign module... done\n"); + + + // NOTE: To finish the initialization of our own type objects we must + // call PyType_Ready, otherwise we run into a segmentation fault, later on. + // This function is responsible for adding inherited slots from a type's base class. + + PartDesign::Feature ::init(); + PartDesign::Solid ::init(); + PartDesign::DressUp ::init(); + PartDesign::SketchBased ::init(); + PartDesign::Subtractive ::init(); + PartDesign::Additive ::init(); + PartDesign::Transformed ::init(); + PartDesign::Mirrored ::init(); + PartDesign::LinearPattern ::init(); + PartDesign::PolarPattern ::init(); + PartDesign::Scaled ::init(); + PartDesign::MultiTransform ::init(); + PartDesign::Hole ::init(); + PartDesign::Body ::init(); + PartDesign::Pad ::init(); + PartDesign::Pocket ::init(); + PartDesign::Fillet ::init(); + PartDesign::Revolution ::init(); + PartDesign::Groove ::init(); + PartDesign::Chamfer ::init(); +<<<<<<< b1f11745d3f535813e5dea41f7a12b14fbd6389f + PartDesign::Draft ::init(); +======= + PartDesign::Face ::init(); + PartDesign::Draft ::init(); + PartDesign::Datum ::init(); + PartDesign::Plane ::init(); + PartDesign::Line ::init(); + PartDesign::Point ::init(); +>>>>>>> Second step for implementing datum features +} + +} // extern "C" diff --git a/src/Mod/PartDesign/App/DatumFeature.cpp b/src/Mod/PartDesign/App/DatumFeature.cpp index 9eb9fa899..0d4148f59 100644 --- a/src/Mod/PartDesign/App/DatumFeature.cpp +++ b/src/Mod/PartDesign/App/DatumFeature.cpp @@ -50,11 +50,6 @@ #define M_PI 3.14159265358979323846 #endif - -namespace PartDesign { - const App::PropertyFloatConstraint::Constraints angleRange = {0.0f,360.0f,1.0f}; -} - using namespace PartDesign; @@ -62,7 +57,8 @@ PROPERTY_SOURCE_ABSTRACT(PartDesign::Datum, PartDesign::Feature) Datum::Datum(void) { - ADD_PROPERTY_TYPE(References,(0,0),"Vertex",(App::PropertyType)(App::Prop_None),"References defining the vertex"); + ADD_PROPERTY_TYPE(References,(0,0),"References",(App::PropertyType)(App::Prop_None),"References defining the datum feature"); + ADD_PROPERTY(Values,(0.0)); touch(); } @@ -72,40 +68,34 @@ Datum::~Datum() short Datum::mustExecute(void) const { - if (References.isTouched()) + if (References.isTouched() || + Values.isTouched()) return 1; return Feature::mustExecute(); } void Datum::onChanged(const App::Property* prop) { - if (!isRestoring()) { - try { - App::DocumentObjectExecReturn *ret = recompute(); - delete ret; - } - catch (...) { - } - } + PartDesign::Feature::onChanged(prop); } -PROPERTY_SOURCE(PartDesign::Vertex, PartDesign::Datum) +PROPERTY_SOURCE(PartDesign::Point, PartDesign::Datum) -Vertex::Vertex() +Point::Point() { } -Vertex::~Vertex() +Point::~Point() { } -short Vertex::mustExecute() const +short Point::mustExecute() const { return PartDesign::Datum::mustExecute(); } -App::DocumentObjectExecReturn *Vertex::execute(void) +App::DocumentObjectExecReturn *Point::execute(void) { gp_Pnt point(0,0,0); // TODO: Find the point @@ -153,22 +143,17 @@ PROPERTY_SOURCE(PartDesign::Plane, PartDesign::Datum) Plane::Plane() { - ADD_PROPERTY_TYPE(Offset,(10.0),"Plane",App::Prop_None,"The offset from the reference"); - ADD_PROPERTY_TYPE(Angle ,(0.0),"Plane",App::Prop_None,"The angle to the reference"); } short Plane::mustExecute() const { - if (Offset.isTouched() || - Angle.isTouched() ) - return 1; return PartDesign::Datum::mustExecute(); } App::DocumentObjectExecReturn *Plane::execute(void) { - double O = this->Offset.getValue(); - double A = this->Angle.getValue(); + double O = 10.0; //this->Offset.getValue(); + double A = 45.0; //this->Angle.getValue(); if (fabs(A) > 360.0) return new App::DocumentObjectExecReturn("Angle too large (please use -360.0 .. +360.0)"); diff --git a/src/Mod/PartDesign/App/DatumFeature.h b/src/Mod/PartDesign/App/DatumFeature.h index 6053abeae..e0c26a62c 100644 --- a/src/Mod/PartDesign/App/DatumFeature.h +++ b/src/Mod/PartDesign/App/DatumFeature.h @@ -41,25 +41,31 @@ public: /// The references defining the datum object, e.g. three planes for a point, two planes for a line App::PropertyLinkSubList References; + /// The values defining the datum object, e.g. the offset from a Reference plane + App::PropertyFloatList Values; /** @name methods override feature */ //@{ /// recalculate the feature App::DocumentObjectExecReturn *execute(void) = 0; short mustExecute() const; + /// returns the type name of the view provider + const char* getViewProviderName(void) const { + return "PartDesignGui::ViewProviderDatum"; + } //@} protected: void onChanged (const App::Property* prop); }; -class PartDesignExport Vertex : public PartDesign::Datum +class PartDesignExport Point : public PartDesign::Datum { - PROPERTY_HEADER(PartDesign::Vertex); + PROPERTY_HEADER(PartDesign::Point); public: - Vertex(); - virtual ~Vertex(); + Point(); + virtual ~Point(); /** @name methods override feature */ //@{ @@ -92,9 +98,6 @@ class PartDesignExport Plane : public PartDesign::Datum public: Plane(); - App::PropertyFloat Offset; - App::PropertyFloatConstraint Angle; - /** @name methods override feature */ //@{ /// recalculate the feature diff --git a/src/Mod/PartDesign/Gui/AppPartDesignGui.cpp b/src/Mod/PartDesign/Gui/AppPartDesignGui.cpp index af942d95f..bec1ad5d8 100644 --- a/src/Mod/PartDesign/Gui/AppPartDesignGui.cpp +++ b/src/Mod/PartDesign/Gui/AppPartDesignGui.cpp @@ -48,6 +48,7 @@ #include "ViewProviderPolarPattern.h" #include "ViewProviderScaled.h" #include "ViewProviderMultiTransform.h" +#include "ViewProviderDatum.h" // use a different name to CreateCommand() void CreatePartDesignCommands(void); @@ -119,6 +120,7 @@ PyMODINIT_FUNC initPartDesignGui() PartDesignGui::ViewProviderPolarPattern ::init(); PartDesignGui::ViewProviderScaled ::init(); PartDesignGui::ViewProviderMultiTransform::init(); + PartDesignGui::ViewProviderDatum ::init(); // add resources and reloads the translators loadPartDesignResource(); diff --git a/src/Mod/PartDesign/Gui/CMakeLists.txt b/src/Mod/PartDesign/Gui/CMakeLists.txt index bb951f6cc..f3a67b09b 100644 --- a/src/Mod/PartDesign/Gui/CMakeLists.txt +++ b/src/Mod/PartDesign/Gui/CMakeLists.txt @@ -44,6 +44,7 @@ set(PartDesignGui_MOC_HDRS TaskPolarPatternParameters.h TaskScaledParameters.h TaskMultiTransformParameters.h + TaskDatumParameters.h ) fc_wrap_cpp(PartDesignGui_MOC_SRCS ${PartDesignGui_MOC_HDRS}) SOURCE_GROUP("Moc" FILES ${PartDesignGui_MOC_SRCS}) @@ -66,6 +67,7 @@ set(PartDesignGui_UIC_SRCS TaskPolarPatternParameters.ui TaskScaledParameters.ui TaskMultiTransformParameters.ui + TaskDatumParameters.ui ) qt4_wrap_ui(PartDesignGui_UIC_HDRS ${PartDesignGui_UIC_SRCS}) @@ -102,6 +104,8 @@ SET(PartDesignGuiViewProvider_SRCS ViewProviderScaled.h ViewProviderMultiTransform.cpp ViewProviderMultiTransform.h + ViewProviderDatum.cpp + ViewProviderDatum.h ) SOURCE_GROUP("ViewProvider" FILES ${PartDesignGuiViewProvider_SRCS}) @@ -155,6 +159,9 @@ SET(PartDesignGuiTaskDlgs_SRCS TaskHoleParameters.ui TaskHoleParameters.cpp TaskHoleParameters.h + TaskDatumParameters.ui + TaskDatumParameters.cpp + TaskDatumParameters.h ) SOURCE_GROUP("TaskDialogs" FILES ${PartDesignGuiTaskDlgs_SRCS}) diff --git a/src/Mod/PartDesign/Gui/Command.cpp b/src/Mod/PartDesign/Gui/Command.cpp index f7246ceab..9c9fbc4e0 100644 --- a/src/Mod/PartDesign/Gui/Command.cpp +++ b/src/Mod/PartDesign/Gui/Command.cpp @@ -196,6 +196,263 @@ bool CmdPartDesignMoveTip::isActive(void) return hasActiveDocument(); } +//=========================================================================== +// PartDesign_Datum +//=========================================================================== + +const QString getReferenceString(Gui::Command* cmd) +{ + QString referenceString; + + PartDesign::Body *pcActiveBody = PartDesignGui::getBody(); + if(!pcActiveBody) return QString::fromAscii(""); + + Gui::SelectionFilter GeometryFilter("SELECT Part::Feature SUBELEMENT Face COUNT 1"); + Gui::SelectionFilter EdgeFilter ("SELECT Part::Feature SUBELEMENT Edge COUNT 1"); + Gui::SelectionFilter VertexFilter ("SELECT Part::Feature SUBELEMENT Vertex COUNT 1"); + Gui::SelectionFilter PlaneFilter ("SELECT App::Plane COUNT 1"); + Gui::SelectionFilter PlaneFilter2 ("SELECT PartDesign::Plane COUNT 1"); + + if (EdgeFilter.match()) + GeometryFilter = EdgeFilter; + else if (VertexFilter.match()) + GeometryFilter = VertexFilter; + if (PlaneFilter2.match()) + PlaneFilter = PlaneFilter2; + + if (GeometryFilter.match() || PlaneFilter.match()) { + // get the selected object + if (GeometryFilter.match()) { + Part::Feature *part = static_cast(GeometryFilter.Result[0][0].getObject()); + // FIXME: Reject or warn about feature that is outside of active body, and feature + // that comes after the current insert point (Tip) + const std::vector &sub = GeometryFilter.Result[0][0].getSubNames(); + referenceString = QString::fromAscii("["); + + for (int r = 0; r != sub.size(); r++) { + // get the selected sub shape + const Part::TopoShape &shape = part->Shape.getValue(); + TopoDS_Shape sh = shape.getSubShape(sub[r].c_str()); + if (sh.IsNull()) { + referenceString += QString::fromAscii(r == 0 ? "" : ",") + + QString::fromAscii("(App.activeDocument().") + QString::fromAscii(part->getNameInDocument()) + + QString::fromAscii(",") + QString::fromStdString(sub[r]) + QString::fromAscii(")"); + } + } + + referenceString += QString::fromAscii("]"); + if (referenceString.length() == 2) { + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("No sub shape selected"), + QObject::tr("You have to select a face, edge, vertex or plane to define a datum feature!")); + return QString::fromAscii(""); + } + + return referenceString; + } else { + Part::Feature *part = static_cast(PlaneFilter.Result[0][0].getObject()); + return QString::fromAscii("[(App.activeDocument().") + QString::fromAscii(part->getNameInDocument()) + + QString::fromAscii(",'')]"); + } + } + else { + // Get a valid datum feature from the user + std::vector status; + std::vector refs = cmd->getDocument()->getObjectsOfType(App::Plane::getClassTypeId()); + std::vector refstmp = cmd->getDocument()->getObjectsOfType(PartDesign::Plane::getClassTypeId()); + refs.insert(refs.end(), refstmp.begin(), refstmp.end()); + refstmp = cmd->getDocument()->getObjectsOfType(PartDesign::Line::getClassTypeId()); + refs.insert(refs.end(), refstmp.begin(), refstmp.end()); + refstmp = cmd->getDocument()->getObjectsOfType(PartDesign::Point::getClassTypeId()); + refs.insert(refs.end(), refstmp.begin(), refstmp.end()); + + unsigned validRefs = 0; + std::vector chosenRefs; + + for (std::vector::iterator r = refs.begin(); r != refs.end(); r++) { + // Check whether this reference is a base plane + bool base = false; + for (unsigned i = 0; i < 3; i++) { + if (strcmp(BasePlaneNames[i], (*r)->getNameInDocument()) == 0) { + status.push_back(PartDesignGui::FeaturePickDialog::basePlane); + if (chosenRefs.empty()) + chosenRefs.push_back(*r); + validRefs++; + base = true; + break; + } + } + if (base) continue; + + // Check whether this reference belongs to the active body + PartDesign::Body* body = PartDesignGui::getBody(); + if (!body->hasFeature(*r)) { + status.push_back(PartDesignGui::FeaturePickDialog::otherBody); + continue; + } else { + if (body->isAfterTip(*r)) + status.push_back(PartDesignGui::FeaturePickDialog::afterTip); + continue; + } + + // All checks passed - found a valid reference + if (chosenRefs.empty()) + chosenRefs.push_back(*r); + validRefs++; + status.push_back(PartDesignGui::FeaturePickDialog::validFeature); + } + + if (validRefs == 0) { + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("No valid references in this document"), + QObject::tr("Please select a face, edge or vertex")); + return QString::fromAscii(""); + } + + // If there is more than one possibility, show dialog and let user pick references + if (validRefs > 1) { + PartDesignGui::FeaturePickDialog Dlg(refs, status); + if ((Dlg.exec() != QDialog::Accepted) || (chosenRefs = Dlg.getFeatures()).empty()) + return QString::fromAscii(""); // Cancelled or nothing selected + if (chosenRefs.size() > 3) + Base::Console().Warning("You have chosen more than three references for a datum feature. The extra references are being ignored"); + } + + referenceString = QString::fromAscii("["); + for (int i = 0; i < chosenRefs.size(); i++) { + referenceString += QString::fromAscii(i == 0 ? "" : ",") + + QString::fromAscii("(App.activeDocument().") + QString::fromUtf8(chosenRefs[i]->getNameInDocument()) + + QString::fromAscii(",'')"); + } + + referenceString += QString::fromAscii("]"); + return referenceString; + } +} + +/* Datum feature commands =======================================================*/ + +DEF_STD_CMD_A(CmdPartDesignPlane); + +CmdPartDesignPlane::CmdPartDesignPlane() + :Command("PartDesign_Plane") +{ + sAppModule = "PartDesign"; + sGroup = QT_TR_NOOP("PartDesign"); + sMenuText = QT_TR_NOOP("Create a datum plane"); + sToolTipText = QT_TR_NOOP("Create a new datum plane"); + sWhatsThis = sToolTipText; + sStatusTip = sToolTipText; + sPixmap = "PartDesign_Plane"; +} + +void CmdPartDesignPlane::activated(int iMsg) +{ + // create Datum plane + std::string FeatName = getUniqueObjectName("DatumPlane"); + QString refStr = getReferenceString(this); + PartDesign::Body *pcActiveBody = PartDesignGui::getBody(); + + openCommand("Create a datum plane"); + doCommand(Doc,"App.activeDocument().addObject('PartDesign::Plane','%s')",FeatName.c_str()); + if (refStr.length() > 0) + doCommand(Doc,"App.activeDocument().%s.References = %s",FeatName.c_str(),refStr.toStdString().c_str()); + doCommand(Doc,"App.activeDocument().%s.Values = [10.0]",FeatName.c_str()); + doCommand(Doc,"App.activeDocument().%s.addFeature(App.activeDocument().%s)", + pcActiveBody->getNameInDocument(), FeatName.c_str()); + doCommand(Gui,"App.activeDocument().recompute()"); // recompute the feature based on its references + doCommand(Gui,"Gui.activeDocument().setEdit('%s')",FeatName.c_str()); + +} + +bool CmdPartDesignPlane::isActive(void) +{ + if (getActiveGuiDocument()) + return true; + else + return false; +} + +DEF_STD_CMD_A(CmdPartDesignLine); + +CmdPartDesignLine::CmdPartDesignLine() + :Command("PartDesign_Line") +{ + sAppModule = "PartDesign"; + sGroup = QT_TR_NOOP("PartDesign"); + sMenuText = QT_TR_NOOP("Create a datum line"); + sToolTipText = QT_TR_NOOP("Create a new datum line"); + sWhatsThis = sToolTipText; + sStatusTip = sToolTipText; + sPixmap = "PartDesign_Line"; +} + +void CmdPartDesignLine::activated(int iMsg) +{ + // create Datum line + std::string FeatName = getUniqueObjectName("DatumLine"); + QString refStr = getReferenceString(this); + PartDesign::Body *pcActiveBody = PartDesignGui::getBody(); + + openCommand("Create a datum line"); + doCommand(Doc,"App.activeDocument().addObject('PartDesign::Line','%s')",FeatName.c_str()); + if (refStr.length() > 0) + doCommand(Doc,"App.activeDocument().%s.References = %s",FeatName.c_str(),refStr.toStdString().c_str()); + doCommand(Doc,"App.activeDocument().%s.Values = [10.0]",FeatName.c_str()); + doCommand(Doc,"App.activeDocument().%s.addFeature(App.activeDocument().%s)", + pcActiveBody->getNameInDocument(), FeatName.c_str()); + doCommand(Gui,"App.activeDocument().recompute()"); // recompute the feature based on its references + doCommand(Gui,"Gui.activeDocument().setEdit('%s')",FeatName.c_str()); + +} + +bool CmdPartDesignLine::isActive(void) +{ + if (getActiveGuiDocument()) + return true; + else + return false; +} + +DEF_STD_CMD_A(CmdPartDesignPoint); + +CmdPartDesignPoint::CmdPartDesignPoint() + :Command("PartDesign_Point") +{ + sAppModule = "PartDesign"; + sGroup = QT_TR_NOOP("PartDesign"); + sMenuText = QT_TR_NOOP("Create a datum point"); + sToolTipText = QT_TR_NOOP("Create a new datum point"); + sWhatsThis = sToolTipText; + sStatusTip = sToolTipText; + sPixmap = "PartDesign_Point"; +} + +void CmdPartDesignPoint::activated(int iMsg) +{ + // create Datum point + std::string FeatName = getUniqueObjectName("DatumPoint"); + QString refStr = getReferenceString(this); + PartDesign::Body *pcActiveBody = PartDesignGui::getBody(); + + openCommand("Create a datum plane"); + doCommand(Doc,"App.activeDocument().addObject('PartDesign::Point','%s')",FeatName.c_str()); + if (refStr.length() > 0) + doCommand(Doc,"App.activeDocument().%s.References = %s",FeatName.c_str(),refStr.toStdString().c_str()); + doCommand(Doc,"App.activeDocument().%s.Values = [10.0]",FeatName.c_str()); + doCommand(Doc,"App.activeDocument().%s.addFeature(App.activeDocument().%s)", + pcActiveBody->getNameInDocument(), FeatName.c_str()); + doCommand(Gui,"App.activeDocument().recompute()"); // recompute the feature based on its references + doCommand(Gui,"Gui.activeDocument().setEdit('%s')",FeatName.c_str()); + +} + +bool CmdPartDesignPoint::isActive(void) +{ + if (getActiveGuiDocument()) + return true; + else + return false; +} + //=========================================================================== // PartDesign_Sketch //=========================================================================== @@ -1396,18 +1653,21 @@ void CreatePartDesignCommands(void) Gui::CommandManager &rcCmdMgr = Gui::Application::Instance->commandManager(); rcCmdMgr.addCommand(new CmdPartDesignBody()); + rcCmdMgr.addCommand(new CmdPartDesignMoveTip()); + rcCmdMgr.addCommand(new CmdPartDesignPlane()); + rcCmdMgr.addCommand(new CmdPartDesignLine()); + rcCmdMgr.addCommand(new CmdPartDesignPoint()); + rcCmdMgr.addCommand(new CmdPartDesignNewSketch()); rcCmdMgr.addCommand(new CmdPartDesignPad()); rcCmdMgr.addCommand(new CmdPartDesignPocket()); rcCmdMgr.addCommand(new CmdPartDesignRevolution()); rcCmdMgr.addCommand(new CmdPartDesignGroove()); rcCmdMgr.addCommand(new CmdPartDesignFillet()); - rcCmdMgr.addCommand(new CmdPartDesignDraft()); - rcCmdMgr.addCommand(new CmdPartDesignNewSketch()); + rcCmdMgr.addCommand(new CmdPartDesignDraft()); rcCmdMgr.addCommand(new CmdPartDesignChamfer()); rcCmdMgr.addCommand(new CmdPartDesignMirrored()); rcCmdMgr.addCommand(new CmdPartDesignLinearPattern()); rcCmdMgr.addCommand(new CmdPartDesignPolarPattern()); //rcCmdMgr.addCommand(new CmdPartDesignScaled()); rcCmdMgr.addCommand(new CmdPartDesignMultiTransform()); - rcCmdMgr.addCommand(new CmdPartDesignMoveTip()); } diff --git a/src/Mod/PartDesign/Gui/ReferenceSelection.cpp b/src/Mod/PartDesign/Gui/ReferenceSelection.cpp index f2bfcd42e..93880e81e 100644 --- a/src/Mod/PartDesign/Gui/ReferenceSelection.cpp +++ b/src/Mod/PartDesign/Gui/ReferenceSelection.cpp @@ -74,5 +74,8 @@ bool ReferenceSelection::allow(App::Document* pDoc, App::DocumentObject* pObj, c } } } + if (point && subName.size() > 6 && subName.substr(0,6) == "Vertex") { + return true; + } return false; } diff --git a/src/Mod/PartDesign/Gui/ReferenceSelection.h b/src/Mod/PartDesign/Gui/ReferenceSelection.h index 03b634012..efdf62422 100644 --- a/src/Mod/PartDesign/Gui/ReferenceSelection.h +++ b/src/Mod/PartDesign/Gui/ReferenceSelection.h @@ -32,11 +32,12 @@ class ReferenceSelection : public Gui::SelectionFilterGate const App::DocumentObject* support; bool edge, plane; bool planar; + bool point; public: ReferenceSelection(const App::DocumentObject* support_, - const bool edge_, const bool plane_, const bool planar_) + const bool edge_, const bool plane_, const bool planar_, const bool point_ = false) : Gui::SelectionFilterGate((Gui::SelectionFilter*)0), - support(support_), edge(edge_), plane(plane_), planar(planar_) + support(support_), edge(edge_), plane(plane_), planar(planar_), point(point_) { } /** diff --git a/src/Mod/PartDesign/Gui/TaskDatumParameters.cpp b/src/Mod/PartDesign/Gui/TaskDatumParameters.cpp new file mode 100644 index 000000000..21fe6751a --- /dev/null +++ b/src/Mod/PartDesign/Gui/TaskDatumParameters.cpp @@ -0,0 +1,503 @@ +/*************************************************************************** + * Copyright (c) 2013 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 +# include +# include +# include +#endif + +#include "ui_TaskDatumParameters.h" +#include "TaskDatumParameters.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ReferenceSelection.h" +#include "Workbench.h" + +using namespace PartDesignGui; +using namespace Gui; + +/* TRANSLATOR PartDesignGui::TaskDatumParameters */ + +// Create reference name from PropertyLinkSub values in a translatable fashion +const QString makeRefString(const QString& obj, const std::string& sub) +{ + if ((sub.size() > 4) && (sub.substr(4) == "Face")) { + int subId = std::atoi(&sub[4]); + return obj + QObject::tr(":Face") + QString::number(subId); + } else if ((sub.size() > 4) && (sub.substr(4) == "Edge")) { + int subId = std::atoi(&sub[4]); + return obj + QObject::tr(":Edge") + QString::number(subId); + } if ((sub.size() > 6) && (sub.substr(6) == "Vertex")) { + int subId = std::atoi(&sub[6]); + return obj + QObject::tr(":Vertex") + QString::number(subId); + } else { + return QObject::tr("No reference selected"); + } +} + +TaskDatumParameters::TaskDatumParameters(ViewProviderDatum *DatumView,QWidget *parent) + : TaskBox(Gui::BitmapFactory().pixmap("iconName"),tr("Datum parameters"),true, parent),DatumView(DatumView) +{ + TaskBox(Gui::BitmapFactory().pixmap((QString::fromAscii("PartDesign_") + DatumView->datumType).toAscii()), DatumView->datumType + tr(" parameters"), true, parent); + // we need a separate container widget to add all controls to + proxy = new QWidget(this); + ui = new Ui_TaskDatumParameters(); + ui->setupUi(proxy); + QMetaObject::connectSlotsByName(this); + + connect(ui->spinValue1, SIGNAL(valueChanged(double)), + this, SLOT(onValue1Changed(double))); + connect(ui->checkBox1, SIGNAL(toggled(bool)), + this, SLOT(onCheckBox1(bool))); + connect(ui->buttonRef1, SIGNAL(pressed()), + this, SLOT(onButtonRef1())); + connect(ui->lineRef1, SIGNAL(textEdited(QString)), + this, SLOT(onRefName(QString))); + connect(ui->buttonRef2, SIGNAL(pressed()), + this, SLOT(onButtonRef2())); + connect(ui->lineRef2, SIGNAL(textEdited(QString)), + this, SLOT(onRefName(QString))); + connect(ui->buttonRef3, SIGNAL(pressed()), + this, SLOT(onButtonRef3())); + connect(ui->lineRef3, SIGNAL(textEdited(QString)), + this, SLOT(onRefName(QString))); + + this->groupLayout()->addWidget(proxy); + + // Temporarily prevent unnecessary feature recomputes + ui->spinValue1->blockSignals(true); + ui->checkBox1->blockSignals(true); + ui->buttonRef1->blockSignals(true); + ui->lineRef1->blockSignals(true); + ui->buttonRef2->blockSignals(true); + ui->lineRef2->blockSignals(true); + ui->buttonRef3->blockSignals(true); + ui->lineRef3->blockSignals(true); + + // Get the feature data + PartDesign::Datum* pcDatum = static_cast(DatumView->getObject()); + std::vector refs = pcDatum->References.getValues(); + std::vector refnames = pcDatum->References.getSubValues(); + std::vector refstrings; + for (int r = 0; r < 3; r++) + if ((r < refs.size()) && (refs[r] != NULL)) { + refstrings.push_back(makeRefString(QString::fromAscii(refs[r]->getNameInDocument()), refnames[r])); + } else { + refstrings.push_back(tr("No reference selected")); + refnames.push_back(""); + } + + //bool checked1 = pcDatum->Checked.getValue(); + std::vector vals = pcDatum->Values.getValues(); + + // Fill data into dialog elements + ui->spinValue1->setValue(vals[0]); + //ui->checkBox1->setChecked(checked1); + ui->lineRef1->setText(refstrings[0]); + ui->lineRef1->setProperty("RefName", QByteArray(refnames[0].c_str())); + ui->lineRef2->setText(refstrings[1]); + ui->lineRef2->setProperty("RefName", QByteArray(refnames[1].c_str())); + ui->lineRef3->setText(refstrings[2]); + ui->lineRef3->setProperty("RefName", QByteArray(refnames[2].c_str())); + + // activate and de-activate dialog elements as appropriate + ui->spinValue1->blockSignals(false); + ui->checkBox1->blockSignals(false); + ui->buttonRef1->blockSignals(false); + ui->lineRef1->blockSignals(false); + ui->buttonRef2->blockSignals(false); + ui->lineRef2->blockSignals(false); + ui->buttonRef3->blockSignals(false); + ui->lineRef3->blockSignals(false); + updateUI(); +} + +QLineEdit* TaskDatumParameters::getCurrentLine() +{ + if (refSelectionMode == 0) + return ui->lineRef1; + else if (refSelectionMode == 1) + return ui->lineRef2; + else if (refSelectionMode == 2) + return ui->lineRef3; + else + return NULL; +} + +void TaskDatumParameters::updateUI() +{ + ui->checkBox1->setEnabled(false); + onButtonRef1(true); +} + +void TaskDatumParameters::onSelectionChanged(const Gui::SelectionChanges& msg) +{ + if (msg.Type == Gui::SelectionChanges::AddSelection) { + if (refSelectionMode < 0) + return; + // Don't allow selection in other document + if (strcmp(msg.pDocName, DatumView->getObject()->getDocument()->getName()) != 0) + return; + + if (!msg.pSubName || msg.pSubName[0] == '\0') + return; + std::string subName(msg.pSubName); + if (((subName.size() > 4) && (subName.substr(0,4) != "Face") && (subName.substr(0,4) != "Edge")) || + ((subName.size() > 6) && (subName.substr(0,6) != "Vertex"))) + return; + + // Don't allow selection outside Tip solid feature + App::DocumentObject* solid = PartDesignGui::ActivePartObject->getPrevSolidFeature(); + if (solid == NULL) { + // There is no solid feature yet, so we can't select from it... + // Turn off reference selection mode + onButtonRef1(false); + return; + } + if (strcmp(msg.pObjectName, solid->getNameInDocument()) != 0) + return; + + PartDesign::Datum* pcDatum = static_cast(DatumView->getObject()); + std::vector refs = pcDatum->References.getValues(); + std::vector refnames = pcDatum->References.getSubValues(); + if (refSelectionMode < refs.size()) { + refs[refSelectionMode] = solid; + refnames[refSelectionMode] = subName; + } else { + refs.push_back(solid); + refnames.push_back(subName); + } + pcDatum->References.setValues(refs, refnames); + pcDatum->getDocument()->recomputeFeature(pcDatum); + + QLineEdit* line = getCurrentLine(); + if (line != NULL) { + line->blockSignals(true); + line->setText(makeRefString(QString::fromAscii(solid->getNameInDocument()), subName)); + line->setProperty("RefName", QByteArray(subName.c_str())); + line->blockSignals(false); + } + + // Turn off reference selection mode + onButtonRef1(false); + } + else if (msg.Type == Gui::SelectionChanges::ClrSelection) { + QLineEdit* line = getCurrentLine(); + if (line != NULL) { + line->blockSignals(true); + line->setText(tr("No reference selected")); + line->setProperty("RefName", QByteArray()); + line->blockSignals(false); + } + } +} + +void TaskDatumParameters::onValue1Changed(double val) +{ + PartDesign::Datum* pcDatum = static_cast(DatumView->getObject()); + std::vector vals = pcDatum->Values.getValues(); + vals[0] = val; + pcDatum->Values.setValues(vals); + pcDatum->getDocument()->recomputeFeature(pcDatum); +} + +void TaskDatumParameters::onCheckBox1(bool on) +{ + PartDesign::Datum* pcDatum = static_cast(DatumView->getObject()); + //pcDatum->Reversed.setValue(on); + pcDatum->getDocument()->recomputeFeature(pcDatum); +} + +void TaskDatumParameters::onButtonRef(const bool pressed, const int idx) +{ + App::DocumentObject* solid = PartDesignGui::ActivePartObject->getPrevSolidFeature(); + if (solid == NULL) { + // There is no solid feature, so we can't select from it... + return; + } + + if (pressed) { + Gui::Document* doc = Gui::Application::Instance->activeDocument(); + if (doc) { + doc->setHide(DatumView->getObject()->getNameInDocument()); + doc->setShow(solid->getNameInDocument()); + } + Gui::Selection().clearSelection(); + Gui::Selection().addSelectionGate + (new ReferenceSelection(solid, true, true, false, true)); + refSelectionMode = idx; + } else { + Gui::Selection().rmvSelectionGate(); + Gui::Document* doc = Gui::Application::Instance->activeDocument(); + if (doc) { + doc->setShow(DatumView->getObject()->getNameInDocument()); + doc->setHide(solid->getNameInDocument()); + } + + refSelectionMode = -1; + } +} + +void TaskDatumParameters::onButtonRef1(const bool pressed) { + onButtonRef(pressed, 0); + // Update button if onButtonRef1() is called explicitly + ui->buttonRef1->setChecked(pressed); +} +void TaskDatumParameters::onButtonRef2(const bool pressed) { + onButtonRef(pressed, 1); + // Update button if onButtonRef1() is called explicitly + ui->buttonRef2->setChecked(pressed); +} +void TaskDatumParameters::onButtonRef3(const bool pressed) { + onButtonRef(pressed, 2); + // Update button if onButtonRef1() is called explicitly + ui->buttonRef3->setChecked(pressed); +} + +void TaskDatumParameters::onRefName(const QString& text) +{ + // We must expect that "text" is the translation of "Face", "Edge" or "Vertex" followed by an ID. + QString name; + QTextStream str(&name); + QRegExp rx(name); + std::stringstream ss; + QLineEdit* line = getCurrentLine(); + if (line == NULL) return; + + str << "^" << tr("Face") << "(\\d+)$"; + if (text.indexOf(rx) < 0) { + line->setProperty("RefName", QByteArray()); + return; + } else { + int faceId = rx.cap(1).toInt(); + ss << "Face" << faceId; + } + str << "^" << tr("Edge") << "(\\d+)$"; + if (text.indexOf(rx) < 0) { + line->setProperty("RefName", QByteArray()); + return; + } else { + int lineId = rx.cap(1).toInt(); + ss << "Edge" << lineId; + } + str << "^" << tr("Vertex") << "(\\d+)$"; + if (text.indexOf(rx) < 0) { + line->setProperty("RefName", QByteArray()); + return; + } else { + int vertexId = rx.cap(1).toInt(); + ss << "Vertex" << vertexId; + } + line->setProperty("RefName", QByteArray(ss.str().c_str())); + + PartDesign::Datum* pcDatum = static_cast(DatumView->getObject()); + App::DocumentObject* solid = PartDesignGui::ActivePartObject->getPrevSolidFeature(); + if (solid == NULL) { + // There is no solid, so we can't select from it... + return; + } + std::vector refs = pcDatum->References.getValues(); + std::vector refnames = pcDatum->References.getSubValues(); + if (refSelectionMode < refs.size()) { + refs[refSelectionMode] = solid; + refnames[refSelectionMode] = ss.str(); + } else { + refs.push_back(solid); + refnames.push_back(ss.str()); + } + pcDatum->References.setValues(refs, refnames); + pcDatum->getDocument()->recomputeFeature(pcDatum); +} + +double TaskDatumParameters::getValue1() const +{ + return ui->spinValue1->value(); +} + +bool TaskDatumParameters::getCheck1() const +{ + return ui->checkBox1->isChecked(); +} + +QString TaskDatumParameters::getRefName(const int idx) const +{ + if (idx == 0) + return ui->lineRef1->property("RefName").toString(); + else if (idx == 1) + return ui->lineRef2->property("RefName").toString(); + else if (idx == 2) + return ui->lineRef3->property("RefName").toString(); +} + +TaskDatumParameters::~TaskDatumParameters() +{ + delete ui; +} + +void TaskDatumParameters::changeEvent(QEvent *e) +{ + TaskBox::changeEvent(e); + if (e->type() == QEvent::LanguageChange) { + ui->spinValue1->blockSignals(true); + ui->checkBox1->blockSignals(true); + ui->buttonRef1->blockSignals(true); + ui->lineRef1->blockSignals(true); + ui->buttonRef2->blockSignals(true); + ui->lineRef2->blockSignals(true); + ui->buttonRef3->blockSignals(true); + ui->lineRef3->blockSignals(true); + ui->retranslateUi(proxy); + + PartDesign::Datum* pcDatum = static_cast(DatumView->getObject()); + std::vector refs = pcDatum->References.getValues(); + std::vector refnames = pcDatum->References.getSubValues(); + std::vector refstrings; + for (int r = 0; r < 3; r++) + if ((r < refs.size()) && (refs[r] != NULL)) + refstrings.push_back(makeRefString(QString::fromAscii(refs[r]->getNameInDocument()), refnames[r])); + else + refstrings.push_back(tr("No reference selected")); + + ui->lineRef1->setText(refstrings[0]); + ui->lineRef2->setText(refstrings[1]); + ui->lineRef3->setText(refstrings[2]); + + ui->spinValue1->blockSignals(false); + ui->checkBox1->blockSignals(false); + ui->buttonRef1->blockSignals(false); + ui->lineRef1->blockSignals(false); + ui->buttonRef2->blockSignals(false); + ui->lineRef2->blockSignals(false); + ui->buttonRef3->blockSignals(false); + ui->lineRef3->blockSignals(false); + } +} + +//************************************************************************** +//************************************************************************** +// TaskDialog +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +TaskDlgDatumParameters::TaskDlgDatumParameters(ViewProviderDatum *DatumView) + : TaskDialog(),DatumView(DatumView) +{ + assert(DatumView); + parameter = new TaskDatumParameters(DatumView); + + Content.push_back(parameter); +} + +TaskDlgDatumParameters::~TaskDlgDatumParameters() +{ + +} + +//==== calls from the TaskView =============================================================== + + +void TaskDlgDatumParameters::open() +{ + +} + +void TaskDlgDatumParameters::clicked(int) +{ + +} + +bool TaskDlgDatumParameters::accept() +{ + std::string name = DatumView->getObject()->getNameInDocument(); + + try { + Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Values = [%f]",name.c_str(),parameter->getValue1()); + //Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Checked = %i",name.c_str(),parameter->getCheckBox1()?1:0); + + App::DocumentObject* solid = PartDesignGui::ActivePartObject->getPrevSolidFeature(); + if (solid != NULL) { + QString buf = QString::fromAscii("["); + for (int r = 0; r < 3; r++) { + QString refname = parameter->getRefName(r); + if (refname != tr("No reference selected")) + buf += QString::fromAscii(r == 0 ? "" : ",") + + QString::fromAscii("App.activeDocument().") + QString::fromUtf8(solid->getNameInDocument()) + + QString::fromAscii(",") + refname + QString::fromAscii(")"); + } + buf += QString::fromAscii("]"); + if (buf.size() > 2) + Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.References = %s", name.c_str(), buf.toStdString().c_str()); + } + + Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.recompute()"); + if (!DatumView->getObject()->isValid()) + throw Base::Exception(DatumView->getObject()->getStatusString()); + Gui::Command::doCommand(Gui::Command::Gui,"Gui.activeDocument().resetEdit()"); + Gui::Command::commitCommand(); + } + catch (const Base::Exception& e) { + QMessageBox::warning(parameter, tr("Datum dialog: Input error"), QString::fromAscii(e.what())); + return false; + } + + return true; +} + +bool TaskDlgDatumParameters::reject() +{ + // roll back the done things + Gui::Command::abortCommand(); + Gui::Command::doCommand(Gui::Command::Gui,"Gui.activeDocument().resetEdit()"); + + // Body housekeeping + if (ActivePartObject != NULL) { + // Make the new Tip and the previous solid feature visible again + App::DocumentObject* tip = ActivePartObject->Tip.getValue(); + App::DocumentObject* prev = ActivePartObject->getPrevSolidFeature(); + if (tip != NULL) { + Gui::Application::Instance->getViewProvider(tip)->show(); + if ((tip != prev) && (prev != NULL)) + Gui::Application::Instance->getViewProvider(prev)->show(); + } + } + + return true; +} + + + +#include "moc_TaskDatumParameters.cpp" diff --git a/src/Mod/PartDesign/Gui/TaskDatumParameters.h b/src/Mod/PartDesign/Gui/TaskDatumParameters.h new file mode 100644 index 000000000..1ab65b860 --- /dev/null +++ b/src/Mod/PartDesign/Gui/TaskDatumParameters.h @@ -0,0 +1,124 @@ +/*************************************************************************** + * Copyright (c) 2013 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 * + * * + ***************************************************************************/ + + +#ifndef GUI_TASKVIEW_TaskDatumParameters_H +#define GUI_TASKVIEW_TaskDatumParameters_H + +#include +#include +#include + +#include "ViewProviderDatum.h" + +class Ui_TaskDatumParameters; + +namespace App { +class Property; +} + +namespace Gui { +class ViewProvider; +} + +namespace PartDesignGui { + + + +class TaskDatumParameters : public Gui::TaskView::TaskBox, public Gui::SelectionObserver +{ + Q_OBJECT + +public: + TaskDatumParameters(ViewProviderDatum *DatumView,QWidget *parent = 0); + ~TaskDatumParameters(); + + QString getRefName(const int idx) const; + double getValue1(void) const; + bool getCheck1(void) const; + +private Q_SLOTS: + void onValue1Changed(double); + void onCheckBox1(bool); + void onRefName(const QString& text); + void onButtonRef1(const bool pressed = true); + void onButtonRef2(const bool pressed = true); + void onButtonRef3(const bool pressed = true); + +protected: + void changeEvent(QEvent *e); + +private: + void onSelectionChanged(const Gui::SelectionChanges& msg); + void updateUI(); + +private: + QWidget* proxy; + Ui_TaskDatumParameters* ui; + ViewProviderDatum *DatumView; + + int refSelectionMode; + + QLineEdit* getCurrentLine(); + void onButtonRef(const bool pressed, const int idx); + +}; + +/// simulation dialog for the TaskView +class TaskDlgDatumParameters : public Gui::TaskView::TaskDialog +{ + Q_OBJECT + +public: + TaskDlgDatumParameters(ViewProviderDatum *DatumView); + ~TaskDlgDatumParameters(); + + ViewProviderDatum* getDatumView() const + { return DatumView; } + + +public: + /// is called the TaskView when the dialog is opened + virtual void open(); + /// is called by the framework if an button is clicked which has no accept or reject role + virtual void clicked(int); + /// is called by the framework if the dialog is accepted (Ok) + virtual bool accept(); + /// is called by the framework if the dialog is rejected (Cancel) + virtual bool reject(); + /// is called by the framework if the user presses the help button + virtual bool isAllowedAlterDocument(void) const + { return false; } + + /// returns for Close and Help button + virtual QDialogButtonBox::StandardButtons getStandardButtons(void) const + { return QDialogButtonBox::Ok|QDialogButtonBox::Cancel; } + +protected: + ViewProviderDatum *DatumView; + + TaskDatumParameters *parameter; +}; + +} //namespace PartDesignGui + +#endif // GUI_TASKVIEW_TASKAPPERANCE_H diff --git a/src/Mod/PartDesign/Gui/TaskDatumParameters.ui b/src/Mod/PartDesign/Gui/TaskDatumParameters.ui new file mode 100644 index 000000000..b8987e098 --- /dev/null +++ b/src/Mod/PartDesign/Gui/TaskDatumParameters.ui @@ -0,0 +1,97 @@ + + + PartDesignGui::TaskDatumParameters + + + + 0 + 0 + 272 + 192 + + + + Form + + + + + + + + Reference 1 + + + + + + + + + + + + + + Reference 2 + + + + + + + + + + + + + + Reference 3 + + + + + + + + + + + + + + Offset + + + + + + + 0.000000000000000 + + + 999999999.000000000000000 + + + 5.000000000000000 + + + 10.000000000000000 + + + + + + + + + Flip sides + + + + + + + + diff --git a/src/Mod/PartDesign/Gui/ViewProviderDatum.cpp b/src/Mod/PartDesign/Gui/ViewProviderDatum.cpp new file mode 100644 index 000000000..133919389 --- /dev/null +++ b/src/Mod/PartDesign/Gui/ViewProviderDatum.cpp @@ -0,0 +1,118 @@ +/*************************************************************************** + * Copyright (c) 2013 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_ +#endif + +#include "ViewProviderDatum.h" +#include "TaskDatumParameters.h" +#include "Workbench.h" +#include +#include + +using namespace PartDesignGui; + +PROPERTY_SOURCE(PartDesignGui::ViewProviderDatum,PartDesignGui::ViewProvider) + +ViewProviderDatum::ViewProviderDatum() +{ +} + +ViewProviderDatum::~ViewProviderDatum() +{ +} + +void ViewProviderDatum::attach(App::DocumentObject *obj) +{ + ViewProvider::attach(obj); + + PartDesign::Datum* pcDatum = static_cast(getObject()); + if (pcDatum->getClassTypeId() == PartDesign::Plane::getClassTypeId()) + datumType = QObject::tr("Plane"); + else if (pcDatum->getClassTypeId() == PartDesign::Line::getClassTypeId()) + datumType = QObject::tr("Line"); + else if (pcDatum->getClassTypeId() == PartDesign::Point::getClassTypeId()) + datumType = QObject::tr("Point"); +} + +void ViewProviderDatum::setupContextMenu(QMenu* menu, QObject* receiver, const char* member) +{ + QAction* act; + act = menu->addAction(QObject::tr("Edit datum ") + datumType, receiver, member); + act->setData(QVariant((int)ViewProvider::Default)); + PartGui::ViewProviderPart::setupContextMenu(menu, receiver, member); +} + +bool ViewProviderDatum::setEdit(int ModNum) +{ + if (ModNum == ViewProvider::Default ) { + // When double-clicking on the item for this datum feature the + // object unsets and sets its edit mode without closing + // the task panel + Gui::TaskView::TaskDialog *dlg = Gui::Control().activeDialog(); + TaskDlgDatumParameters *datumDlg = qobject_cast(dlg); + if (datumDlg && datumDlg->getDatumView() != this) + datumDlg = 0; // another datum feature left open its task panel + if (dlg && !datumDlg) { + QMessageBox msgBox; + msgBox.setText(QObject::tr("A dialog is already open in the task panel")); + msgBox.setInformativeText(QObject::tr("Do you want to close this dialog?")); + msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No); + msgBox.setDefaultButton(QMessageBox::Yes); + int ret = msgBox.exec(); + if (ret == QMessageBox::Yes) + Gui::Control().closeDialog(); + else + return false; + } + + // clear the selection (convenience) + Gui::Selection().clearSelection(); + + // start the edit dialog + if (datumDlg) + Gui::Control().showDialog(datumDlg); + else + Gui::Control().showDialog(new TaskDlgDatumParameters(this)); + + return true; + } + else { + return ViewProviderPart::setEdit(ModNum); + } +} + +void ViewProviderDatum::unsetEdit(int ModNum) +{ + if (ModNum == ViewProvider::Default) { + // when pressing ESC make sure to close the dialog + Gui::Control().closeDialog(); + } + else { + PartGui::ViewProviderPart::unsetEdit(ModNum); + } +} + + diff --git a/src/Mod/PartDesign/Gui/ViewProviderDatum.h b/src/Mod/PartDesign/Gui/ViewProviderDatum.h new file mode 100644 index 000000000..acb4a89b3 --- /dev/null +++ b/src/Mod/PartDesign/Gui/ViewProviderDatum.h @@ -0,0 +1,59 @@ +/*************************************************************************** + * Copyright (c) 2013 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 * + * * + ***************************************************************************/ + + +#ifndef PARTGUI_ViewProviderDatum_H +#define PARTGUI_ViewProviderDatum_H + +#include "ViewProvider.h" + +namespace PartDesignGui { + +class PartDesignGuiExport ViewProviderDatum : public ViewProvider +{ + PROPERTY_HEADER(PartDesignGui::ViewProviderDatum); + +public: + /// constructor + ViewProviderDatum(); + /// destructor + virtual ~ViewProviderDatum(); + + /// grouping handling + void setupContextMenu(QMenu*, QObject*, const char*); + + virtual void attach(App::DocumentObject *); + + /// The datum type (Plane, Line or Point) + QString datumType; + +protected: + virtual bool setEdit(int ModNum); + virtual void unsetEdit(int ModNum); + +}; + + +} // namespace PartDesignGui + + +#endif // PARTGUI_ViewProviderPad_H diff --git a/src/Mod/PartDesign/Gui/Workbench.cpp b/src/Mod/PartDesign/Gui/Workbench.cpp index 5208ab97f..d1905c709 100644 --- a/src/Mod/PartDesign/Gui/Workbench.cpp +++ b/src/Mod/PartDesign/Gui/Workbench.cpp @@ -98,10 +98,24 @@ void Workbench::activated() std::vector Watcher; + const char* Vertex[] = { + "PartDesign_Plane", + "PartDesign_Line", + "PartDesign_Point", + 0}; + Watcher.push_back(new Gui::TaskView::TaskWatcherCommands( + "SELECT Part::Feature SUBELEMENT Vertex COUNT 1..", + Vertex, + "Vertex tools", + "Part_Box" + )); const char* Edge[] = { "PartDesign_Fillet", "PartDesign_Chamfer", + "PartDesign_Plane", + "PartDesign_Line", + "PartDesign_Point", 0}; Watcher.push_back(new Gui::TaskView::TaskWatcherCommands( "SELECT Part::Feature SUBELEMENT Edge COUNT 1..", @@ -111,10 +125,13 @@ void Workbench::activated() )); const char* Face[] = { - "PartDesign_NewSketch", + "PartDesign_NewSketch", "PartDesign_Fillet", "PartDesign_Chamfer", "PartDesign_Draft", + "PartDesign_Plane", + "PartDesign_Line", + "PartDesign_Point", 0}; Watcher.push_back(new Gui::TaskView::TaskWatcherCommands( "SELECT Part::Feature SUBELEMENT Face COUNT 1", @@ -135,6 +152,9 @@ void Workbench::activated() const char* Plane1[] = { "PartDesign_NewSketch", + "PartDesign_Plane", + "PartDesign_Line", + "PartDesign_Point", 0}; Watcher.push_back(new Gui::TaskView::TaskWatcherCommands( "SELECT App::Plane COUNT 1", @@ -144,6 +164,9 @@ void Workbench::activated() )); const char* Plane2[] = { "PartDesign_NewSketch", + "PartDesign_Plane", + "PartDesign_Line", + "PartDesign_Point", 0}; Watcher.push_back(new Gui::TaskView::TaskWatcherCommands( "SELECT PartDesign::Plane COUNT 1", @@ -152,6 +175,30 @@ void Workbench::activated() "Part_Box" )); + const char* Line[] = { + "PartDesign_Plane", + "PartDesign_Line", + "PartDesign_Point", + 0}; + Watcher.push_back(new Gui::TaskView::TaskWatcherCommands( + "SELECT PartDesign::Line COUNT 1", + Line, + "Start Part", + "Part_Box" + )); + + const char* Point[] = { + "PartDesign_Plane", + "PartDesign_Line", + "PartDesign_Point", + 0}; + Watcher.push_back(new Gui::TaskView::TaskWatcherCommands( + "SELECT PartDesign::Point COUNT 1", + Point, + "Start Part", + "Part_Box" + )); + const char* NoSel[] = { "PartDesign_Body", 0}; @@ -276,6 +323,10 @@ Gui::MenuItem* Workbench::setupMenuBar() const << cons << consaccel << "Separator" + << "PartDesign_Plane" + << "PartDesign_Line" + << "PartDesign_Point" + << "Separator" << "PartDesign_Pad" << "PartDesign_Pocket" << "PartDesign_Revolution" @@ -313,6 +364,10 @@ Gui::ToolBarItem* Workbench::setupToolBars() const << "Sketcher_MapSketch" << "Sketcher_LeaveSketch" << "Separator" + << "PartDesign_Plane" + << "PartDesign_Line" + << "PartDesign_Point" + << "Separator" << "PartDesign_Pad" << "PartDesign_Pocket" << "PartDesign_Revolution"