Second step for implementing datum features

This commit is contained in:
jrheinlaender 2013-04-12 16:24:08 +04:30 committed by Stefan Tröger
parent 63f782d8f0
commit 3b81168e41
15 changed files with 1376 additions and 41 deletions

View File

@ -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();
}

View File

@ -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 <Python.h>
#endif
#include <Base/Console.h>
#include <Base/Interpreter.h>
#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"

View File

@ -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)");

View File

@ -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

View File

@ -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();

View File

@ -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})

View File

@ -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<Part::Feature*>(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<std::string> &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<Part::Feature*>(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<PartDesignGui::FeaturePickDialog::featureStatus> status;
std::vector<App::DocumentObject*> refs = cmd->getDocument()->getObjectsOfType(App::Plane::getClassTypeId());
std::vector<App::DocumentObject*> 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<App::DocumentObject*> chosenRefs;
for (std::vector<App::DocumentObject*>::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());
}

View File

@ -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;
}

View File

@ -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_)
{
}
/**

View File

@ -0,0 +1,503 @@
/***************************************************************************
* Copyright (c) 2013 Jan Rheinlaender <jrheinlaender@users.sourceforge.net>*
* *
* 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 <sstream>
# include <QRegExp>
# include <QTextStream>
# include <QMessageBox>
# include <Precision.hxx>
#endif
#include "ui_TaskDatumParameters.h"
#include "TaskDatumParameters.h"
#include <App/Application.h>
#include <App/Document.h>
#include <Gui/Application.h>
#include <Gui/Document.h>
#include <Gui/BitmapFactory.h>
#include <Gui/ViewProvider.h>
#include <Gui/WaitCursor.h>
#include <Base/Console.h>
#include <Gui/Selection.h>
#include <Gui/Command.h>
#include <Mod/PartDesign/App/DatumFeature.h>
#include <Mod/PartDesign/App/Body.h>
#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<PartDesign::Datum*>(DatumView->getObject());
std::vector<App::DocumentObject*> refs = pcDatum->References.getValues();
std::vector<std::string> refnames = pcDatum->References.getSubValues();
std::vector<QString> 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<float> 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<PartDesign::Datum*>(DatumView->getObject());
std::vector<App::DocumentObject*> refs = pcDatum->References.getValues();
std::vector<std::string> 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<PartDesign::Datum*>(DatumView->getObject());
std::vector<float> 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<PartDesign::Datum*>(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<PartDesign::Datum*>(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<App::DocumentObject*> refs = pcDatum->References.getValues();
std::vector<std::string> 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<PartDesign::Datum*>(DatumView->getObject());
std::vector<App::DocumentObject*> refs = pcDatum->References.getValues();
std::vector<std::string> refnames = pcDatum->References.getSubValues();
std::vector<QString> 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"

View File

@ -0,0 +1,124 @@
/***************************************************************************
* Copyright (c) 2013 Jan Rheinlaender <jrheinlaender@users.sourceforge.net> *
* *
* 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 <Gui/TaskView/TaskView.h>
#include <Gui/Selection.h>
#include <Gui/TaskView/TaskDialog.h>
#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

View File

@ -0,0 +1,97 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>PartDesignGui::TaskDatumParameters</class>
<widget class="QWidget" name="PartDesignGui::TaskDatumParameters">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>272</width>
<height>192</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QPushButton" name="buttonRef1">
<property name="text">
<string>Reference 1</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="lineRef1"/>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_5">
<item>
<widget class="QPushButton" name="buttonRef2">
<property name="text">
<string>Reference 2</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="lineRef2"/>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_6">
<item>
<widget class="QPushButton" name="buttonRef3">
<property name="text">
<string>Reference 3</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="lineRef3"/>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Offset</string>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="spinValue1">
<property name="minimum">
<double>0.000000000000000</double>
</property>
<property name="maximum">
<double>999999999.000000000000000</double>
</property>
<property name="singleStep">
<double>5.000000000000000</double>
</property>
<property name="value">
<double>10.000000000000000</double>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QCheckBox" name="checkBox1">
<property name="text">
<string>Flip sides</string>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -0,0 +1,118 @@
/***************************************************************************
* Copyright (c) 2013 Jan Rheinlaender <jrheinlaender@users.sourceforge.net> *
* *
* 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 <Mod/PartDesign/App/DatumFeature.h>
#include <Gui/Control.h>
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<PartDesign::Datum*>(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<TaskDlgDatumParameters *>(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);
}
}

View File

@ -0,0 +1,59 @@
/***************************************************************************
* Copyright (c) 2013 Jan Rheinlaender <jrheinlaender@users.sourceforge.net> *
* *
* 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

View File

@ -98,10 +98,24 @@ void Workbench::activated()
std::vector<Gui::TaskView::TaskWatcher*> 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"