diff --git a/src/Mod/Sketcher/App/SketchObject.cpp b/src/Mod/Sketcher/App/SketchObject.cpp index 7c31b3993..45c126ab0 100644 --- a/src/Mod/Sketcher/App/SketchObject.cpp +++ b/src/Mod/Sketcher/App/SketchObject.cpp @@ -234,7 +234,10 @@ int SketchObject::setDriving(int ConstrId, bool isdriving) type != Radius && type != Angle && type != SnellsLaw) - return -1; + return -2; + + if (!(vals[ConstrId]->First>=0 || vals[ConstrId]->Second>=0 || vals[ConstrId]->Third>=0) && isdriving==true) + return -3; // a constraint that does not have at least one element as not-external-geometry can never be driving. // copy the list std::vector newVals(vals); @@ -245,11 +248,7 @@ int SketchObject::setDriving(int ConstrId, bool isdriving) this->Constraints.setValues(newVals); delete constNew; - int err = solve(); - if (err) - this->Constraints.setValues(vals); - - return err; + return 0; } int SketchObject::getDriving(int ConstrId, bool &isdriving) @@ -273,6 +272,38 @@ int SketchObject::getDriving(int ConstrId, bool &isdriving) return 0; } +int SketchObject::toggleDriving(int ConstrId) +{ + const std::vector &vals = this->Constraints.getValues(); + + if (ConstrId < 0 || ConstrId >= int(vals.size())) + return -1; + + ConstraintType type = vals[ConstrId]->Type; + + if (type != Distance && + type != DistanceX && + type != DistanceY && + type != Radius && + type != Angle && + type != SnellsLaw) + return -2; + + if (!(vals[ConstrId]->First>=0 || vals[ConstrId]->Second>=0 || vals[ConstrId]->Third>=0) && vals[ConstrId]->isDriving==false) + return -3; // a constraint that does not have at least one element as not-external-geometry can never be driving. + + // copy the list + std::vector newVals(vals); + // clone the changed Constraint + Constraint *constNew = vals[ConstrId]->clone(); + constNew->isDriving = !constNew->isDriving; + newVals[ConstrId] = constNew; + this->Constraints.setValues(newVals); + delete constNew; + + return 0; +} + int SketchObject::movePoint(int GeoId, PointPos PosId, const Base::Vector3d& toPoint, bool relative) { Sketch sketch; @@ -489,7 +520,7 @@ int SketchObject::setConstruction(int GeoId, bool on) newVals[GeoId]=geoNew; this->Geometry.setValues(newVals); - this->Constraints.acceptGeometry(getCompleteGeometry()); + //this->Constraints.acceptGeometry(getCompleteGeometry()); <= This is not necessary for a toggle. Reducing redundant solving. Abdullah return 0; } diff --git a/src/Mod/Sketcher/App/SketchObject.h b/src/Mod/Sketcher/App/SketchObject.h index 0be407c5e..5473392fb 100644 --- a/src/Mod/Sketcher/App/SketchObject.h +++ b/src/Mod/Sketcher/App/SketchObject.h @@ -114,6 +114,8 @@ public: int setDriving(int ConstrId, bool isdriving); /// get the driving status of this constraint int getDriving(int ConstrId, bool &isdriving); + /// toggle the driving status of this constraint + int toggleDriving(int ConstrId); /// move this point to a new location and solve int movePoint(int GeoId, PointPos PosId, const Base::Vector3d& toPoint, bool relative=false); /// retrieves the coordinates of a point diff --git a/src/Mod/Sketcher/App/SketchObjectPy.xml b/src/Mod/Sketcher/App/SketchObjectPy.xml index ccc48516d..e93dcbdc8 100644 --- a/src/Mod/Sketcher/App/SketchObjectPy.xml +++ b/src/Mod/Sketcher/App/SketchObjectPy.xml @@ -87,6 +87,11 @@ Get the Driving status of a datum constraint + + + + toggle the Driving status of a datum constraint + diff --git a/src/Mod/Sketcher/App/SketchObjectPyImp.cpp b/src/Mod/Sketcher/App/SketchObjectPyImp.cpp index 62fe6738f..924c08bc8 100644 --- a/src/Mod/Sketcher/App/SketchObjectPyImp.cpp +++ b/src/Mod/Sketcher/App/SketchObjectPyImp.cpp @@ -49,7 +49,7 @@ using namespace Sketcher; // returns a string which represents the object e.g. when printed in python std::string SketchObjectPy::representation(void) const -{ +{ return ""; } @@ -578,7 +578,7 @@ PyObject* SketchObjectPy::setDriving(PyObject *args) if (this->getSketchObjectPtr()->setDriving(constrid, PyObject_IsTrue(driving) ? true : false)) { std::stringstream str; - str << "Not able set Driving for constraint with the given index: " << constrid; + str << "Not able set Driving/reference for constraint with the given index: " << constrid; PyErr_SetString(PyExc_ValueError, str.str().c_str()); return 0; } @@ -603,6 +603,23 @@ PyObject* SketchObjectPy::getDriving(PyObject *args) return Py::new_reference_to(Py::Boolean(driving)); } +PyObject* SketchObjectPy::toggleDriving(PyObject *args) +{ + int constrid; + + if (!PyArg_ParseTuple(args, "i", &constrid)) + return 0; + + if (this->getSketchObjectPtr()->toggleDriving(constrid)) { + std::stringstream str; + str << "Not able toggle Driving for constraint with the given index: " << constrid; + PyErr_SetString(PyExc_ValueError, str.str().c_str()); + return 0; + } + + Py_Return; +} + PyObject* SketchObjectPy::movePoint(PyObject *args) { diff --git a/src/Mod/Sketcher/Gui/CommandConstraints.cpp b/src/Mod/Sketcher/Gui/CommandConstraints.cpp index 73facc63a..564e4659e 100644 --- a/src/Mod/Sketcher/Gui/CommandConstraints.cpp +++ b/src/Mod/Sketcher/Gui/CommandConstraints.cpp @@ -2869,10 +2869,10 @@ void CmdSketcherConstrainSnellsLaw::activated(int iMsg) std::swap(PosId2,PosId3); } - bool allexternal=false; //a bunch of validity checks if ((GeoId1 < 0 && GeoId2 < 0 && GeoId3 < 0)) { - allexternal=true; + strError = QObject::tr("Can not create constraint with external geometry only!!", dmbg); + throw(Base::Exception("")); } if (!(isVertex(GeoId1,PosId1) && !isSimpleVertex(Obj, GeoId1, PosId1) && @@ -2884,29 +2884,27 @@ void CmdSketcherConstrainSnellsLaw::activated(int iMsg) double n2divn1=0; - if(!allexternal){ - //the essence. - //Unlike other constraints, we'll ask for a value immediately. - QDialog dlg(Gui::getMainWindow()); - Ui::InsertDatum ui_Datum; - ui_Datum.setupUi(&dlg); - dlg.setWindowTitle(EditDatumDialog::tr("Refractive index ratio", dmbg)); - ui_Datum.label->setText(EditDatumDialog::tr("Ratio n2/n1:", dmbg)); - Base::Quantity init_val; - init_val.setUnit(Base::Unit()); - init_val.setValue(0.0); + //the essence. + //Unlike other constraints, we'll ask for a value immediately. + QDialog dlg(Gui::getMainWindow()); + Ui::InsertDatum ui_Datum; + ui_Datum.setupUi(&dlg); + dlg.setWindowTitle(EditDatumDialog::tr("Refractive index ratio", dmbg)); + ui_Datum.label->setText(EditDatumDialog::tr("Ratio n2/n1:", dmbg)); + Base::Quantity init_val; + init_val.setUnit(Base::Unit()); + init_val.setValue(0.0); - ui_Datum.labelEdit->setValue(init_val); - ui_Datum.labelEdit->setParamGrpPath(QByteArray("User parameter:BaseApp/History/SketcherRefrIndexRatio")); - ui_Datum.labelEdit->setToLastUsedValue(); - ui_Datum.labelEdit->selectNumber(); + ui_Datum.labelEdit->setValue(init_val); + ui_Datum.labelEdit->setParamGrpPath(QByteArray("User parameter:BaseApp/History/SketcherRefrIndexRatio")); + ui_Datum.labelEdit->setToLastUsedValue(); + ui_Datum.labelEdit->selectNumber(); - if (dlg.exec() != QDialog::Accepted) return; - ui_Datum.labelEdit->pushToHistory(); + if (dlg.exec() != QDialog::Accepted) return; + ui_Datum.labelEdit->pushToHistory(); - Base::Quantity newQuant = ui_Datum.labelEdit->value(); - n2divn1 = newQuant.getValue(); - } + Base::Quantity newQuant = ui_Datum.labelEdit->value(); + n2divn1 = newQuant.getValue(); //add constraint openCommand("add Snell's law constraint"); @@ -2925,12 +2923,12 @@ void CmdSketcherConstrainSnellsLaw::activated(int iMsg) Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('SnellsLaw',%d,%d,%d,%d,%d,%.12f)) ", selection[0].getFeatName(),GeoId1,PosId1,GeoId2,PosId2,GeoId3,n2divn1); - if (allexternal || constraintCreationMode==Reference) { // it is a constraint on a external line, make it non-driving + /*if (allexternal || constraintCreationMode==Reference) { // it is a constraint on a external line, make it non-driving const std::vector &ConStr = Obj->Constraints.getValues(); Gui::Command::doCommand(Doc,"App.ActiveDocument.%s.setDriving(%i,%s)", selection[0].getFeatName(),ConStr.size()-1,"False"); - } + }*/ commitCommand(); updateActive(); @@ -3437,6 +3435,83 @@ bool CmdSketcherConstraintCreationMode::isActive(void) return false; } +/* Constrain commands =======================================================*/ +DEF_STD_CMD_A(CmdSketcherToggleDrivingConstraint); + +CmdSketcherToggleDrivingConstraint::CmdSketcherToggleDrivingConstraint() + :Command("Sketcher_ToggleDrivingConstraint") +{ + sAppModule = "Sketcher"; + sGroup = QT_TR_NOOP("Sketcher"); + sMenuText = QT_TR_NOOP("Toggle reference/driving constraint"); + sToolTipText = QT_TR_NOOP("Toggles the currently selected constraint to/from reference mode"); + sWhatsThis = "Sketcher_ToggleDrivingConstraint"; + sStatusTip = sToolTipText; + sPixmap = "Sketcher_ToggleDrivingConstraint"; + sAccel = ""; + eType = ForEdit; +} + +void CmdSketcherToggleDrivingConstraint::activated(int iMsg) +{ + // get the selection + std::vector selection = getSelection().getSelectionEx(); + + // only one sketch with its subelements are allowed to be selected + if (selection.size() != 1) { + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), + QObject::tr("Select constraint(s) from the sketch.")); + return; + } + + // get the needed lists and objects + const std::vector &SubNames = selection[0].getSubNames(); + if (SubNames.empty()) { + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), + QObject::tr("Select constraint(s) from the sketch.")); + return; + } + + // make sure the selected object is the sketch in edit mode + const App::DocumentObject* obj = selection[0].getObject(); + ViewProviderSketch* sketchView = static_cast + (Gui::Application::Instance->getViewProvider(obj)); + + // undo command open + openCommand("Toggle driving from/to non-driving"); + + int succesful=SubNames.size(); + // go through the selected subelements + for (std::vector::const_iterator it=SubNames.begin();it!=SubNames.end();++it){ + // only handle constraints + if (it->size() > 10 && it->substr(0,10) == "Constraint") { + int ConstrId = std::atoi(it->substr(10,4000).c_str()) - 1; + try { + // issue the actual commands to toggle + doCommand(Doc,"App.ActiveDocument.%s.toggleDriving(%d) ",selection[0].getFeatName(),ConstrId); + } + catch(const Base::Exception& e) { + succesful--; + } + } + } + + if(succesful>0) + commitCommand(); + else + abortCommand(); + + updateActive(); + + // clear the selection (convenience) + getSelection().clearSelection(); +} + +bool CmdSketcherToggleDrivingConstraint::isActive(void) +{ + return isCreateConstraintActive( getActiveGuiDocument() ); +} + void CreateSketcherCommandsConstraints(void) { Gui::CommandManager &rcCmdMgr = Gui::Application::Instance->commandManager(); @@ -3459,5 +3534,5 @@ void CreateSketcherCommandsConstraints(void) rcCmdMgr.addCommand(new CmdSketcherConstrainSnellsLaw()); rcCmdMgr.addCommand(new CmdSketcherConstrainInternalAlignment()); rcCmdMgr.addCommand(new CmdSketcherConstraintCreationMode()); - + rcCmdMgr.addCommand(new CmdSketcherToggleDrivingConstraint()); } diff --git a/src/Mod/Sketcher/Gui/CommandCreateGeo.cpp b/src/Mod/Sketcher/Gui/CommandCreateGeo.cpp index bf357ffca..5abad8c25 100644 --- a/src/Mod/Sketcher/Gui/CommandCreateGeo.cpp +++ b/src/Mod/Sketcher/Gui/CommandCreateGeo.cpp @@ -5350,7 +5350,16 @@ void CmdSketcherGeometryCreationMode::activated(int iMsg) bool CmdSketcherGeometryCreationMode::isActive(void) { - return isCreateGeoActive(getActiveGuiDocument()); + Gui::Document * doc=getActiveGuiDocument(); + + if (doc) { + // checks if a Sketch Viewprovider is in Edit and is in no special mode + if (doc->getInEdit() && doc->getInEdit()->isDerivedFrom + (SketcherGui::ViewProviderSketch::getClassTypeId())) { + return true; + } + } + return false; } void CreateSketcherCommandsCreateGeo(void) diff --git a/src/Mod/Sketcher/Gui/TaskSketcherConstrains.cpp b/src/Mod/Sketcher/Gui/TaskSketcherConstrains.cpp index 5ae5ad382..6e369bbe1 100644 --- a/src/Mod/Sketcher/Gui/TaskSketcherConstrains.cpp +++ b/src/Mod/Sketcher/Gui/TaskSketcherConstrains.cpp @@ -136,7 +136,7 @@ void ConstraintView::contextMenuEvent (QContextMenuEvent* event) { ConstraintItem *it = dynamic_cast(item); - QAction* driven = menu.addAction(it->isDriving?tr("Change to reference"):tr("Change to driving"), this, SLOT(updateDrivingStatus())); + QAction* driven = menu.addAction(tr("Toggle to/from reference"), this, SLOT(updateDrivingStatus())); // if its the right constraint if ((it->Type == Sketcher::Distance || it->Type == Sketcher::DistanceX || @@ -349,21 +349,8 @@ void TaskSketcherConstrains::on_listWidgetConstraints_updateDrivingStatus(QListW ConstraintItem *it = dynamic_cast(item); if (!item) return; - const std::vector< Sketcher::Constraint * > &vals = sketchView->getSketchObject()->Constraints.getValues(); - - try { - Gui::Command::openCommand("Modify driving status of constraint"); - Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.setDriving(%i,%s)", - this->sketchView->getSketchObject()->getNameInDocument(), - it->ConstraintNbr, - status?"True":"False"); - Gui::Command::commitCommand(); - Gui::Command::updateActive(); - } - catch (const Base::Exception& e) { - Gui::Command::abortCommand(); - } - + Gui::Application::Instance->commandManager().runCommandByName("Sketcher_ToggleDrivingConstraint"); + slotConstraintsChanged(); } diff --git a/src/Mod/Sketcher/Gui/TaskSketcherConstrains.ui b/src/Mod/Sketcher/Gui/TaskSketcherConstrains.ui index 3e3ba1f9e..e344479f3 100644 --- a/src/Mod/Sketcher/Gui/TaskSketcherConstrains.ui +++ b/src/Mod/Sketcher/Gui/TaskSketcherConstrains.ui @@ -50,7 +50,7 @@ - Non-Driving + Reference diff --git a/src/Mod/Sketcher/Gui/Workbench.cpp b/src/Mod/Sketcher/Gui/Workbench.cpp index 2956a1732..3d49e9a87 100644 --- a/src/Mod/Sketcher/Gui/Workbench.cpp +++ b/src/Mod/Sketcher/Gui/Workbench.cpp @@ -206,6 +206,7 @@ inline void SketcherAddWorkbenchConstraints(Gui::MenuItem& cons){ << "Sketcher_ConstrainSnellsLaw" << "Sketcher_ConstrainInternalAlignment" << "Separator" + << "Sketcher_ToggleDrivingConstraint" << "Sketcher_ConstraintCreationMode"; } @@ -229,6 +230,7 @@ inline void SketcherAddWorkbenchConstraints(Gui::ToolBarItem& << "Sketcher_ConstrainAngle" << "Sketcher_ConstrainSnellsLaw" << "Separator" + << "Sketcher_ToggleDrivingConstraint" << "Sketcher_ConstraintCreationMode"; }