[Sketcher] Constraint driving/driven status integration in dimension edition dialog

This integrates the ability to manage dimensional constraint driving/driven status
 in the constraint edition dialog box.
 It adds a checkbox in the dialog to show/select whether a constraint is driving or
 driven. When the constraint value is modified, it is automatically set as driving.
 Main focus is to allow to edit name (alias) of reference (driven) constraints
 directly in the constraint edition box.

 Resolves #3793, #3978
This commit is contained in:
0penBrain
2020-03-17 22:15:04 +01:00
committed by wmayer
parent 71192a9129
commit d520de1aba
6 changed files with 149 additions and 174 deletions

View File

@@ -26,6 +26,7 @@ set(SketcherGui_LIBS
)
set(SketcherGui_MOC_HDRS
EditDatumDialog.h
TaskSketcherConstrains.h
TaskSketcherElements.h
TaskSketcherCreateCommands.h

View File

@@ -86,107 +86,6 @@ bool isCreateConstraintActive(Gui::Document *doc)
return false;
}
void openEditDatumDialog(Sketcher::SketchObject* sketch, int ConstrNbr)
{
const std::vector<Sketcher::Constraint *> &Constraints = sketch->Constraints.getValues();
Sketcher::Constraint* Constr = Constraints[ConstrNbr];
// Return if constraint doesn't have editable value
if (Constr->isDimensional()) {
QDialog dlg(Gui::getMainWindow());
Ui::InsertDatum ui_ins_datum;
ui_ins_datum.setupUi(&dlg);
double datum = Constr->getValue();
Base::Quantity init_val;
if (Constr->Type == Sketcher::Angle) {
datum = Base::toDegrees<double>(datum);
dlg.setWindowTitle(EditDatumDialog::tr("Insert angle"));
init_val.setUnit(Base::Unit::Angle);
ui_ins_datum.label->setText(EditDatumDialog::tr("Angle:"));
ui_ins_datum.labelEdit->setParamGrpPath(QByteArray("User parameter:BaseApp/History/SketcherAngle"));
}
else if (Constr->Type == Sketcher::Radius) {
dlg.setWindowTitle(EditDatumDialog::tr("Insert radius"));
init_val.setUnit(Base::Unit::Length);
ui_ins_datum.label->setText(EditDatumDialog::tr("Radius:"));
ui_ins_datum.labelEdit->setParamGrpPath(QByteArray("User parameter:BaseApp/History/SketcherLength"));
}
else if (Constr->Type == Sketcher::Diameter) {
dlg.setWindowTitle(EditDatumDialog::tr("Insert diameter"));
init_val.setUnit(Base::Unit::Length);
ui_ins_datum.label->setText(EditDatumDialog::tr("Diameter:"));
ui_ins_datum.labelEdit->setParamGrpPath(QByteArray("User parameter:BaseApp/History/SketcherLength"));
}
else if (Constr->Type == Sketcher::SnellsLaw) {
dlg.setWindowTitle(EditDatumDialog::tr("Refractive index ratio", "Constraint_SnellsLaw"));
ui_ins_datum.label->setText(EditDatumDialog::tr("Ratio n2/n1:", "Constraint_SnellsLaw"));
ui_ins_datum.labelEdit->setParamGrpPath(QByteArray("User parameter:BaseApp/History/SketcherRefrIndexRatio"));
}
else {
dlg.setWindowTitle(EditDatumDialog::tr("Insert length"));
init_val.setUnit(Base::Unit::Length);
ui_ins_datum.label->setText(EditDatumDialog::tr("Length:"));
ui_ins_datum.labelEdit->setParamGrpPath(QByteArray("User parameter:BaseApp/History/SketcherLength"));
}
// e.g. an angle or a distance X or Y applied on a line or two vertexes
init_val.setValue(datum);
ui_ins_datum.labelEdit->setValue(init_val);
ui_ins_datum.labelEdit->selectNumber();
ui_ins_datum.labelEdit->bind(sketch->Constraints.createPath(ConstrNbr));
ui_ins_datum.name->setText(Base::Tools::fromStdString(Constr->Name));
if (dlg.exec()) {
Base::Quantity newQuant = ui_ins_datum.labelEdit->value();
if (newQuant.isQuantity() || (Constr->Type == Sketcher::SnellsLaw && newQuant.isDimensionless())) {
// save the value for the history
ui_ins_datum.labelEdit->pushToHistory();
double newDatum = newQuant.getValue();
try {
if (ui_ins_datum.labelEdit->hasExpression())
ui_ins_datum.labelEdit->apply();
else
Gui::cmdAppObjectArgs(sketch, "setDatum(%i,App.Units.Quantity('%f %s'))",
ConstrNbr, newDatum, (const char*)newQuant.getUnit().getString().toUtf8());
QString constraintName = ui_ins_datum.name->text().trimmed();
if (Base::Tools::toStdString(constraintName) != sketch->Constraints[ConstrNbr]->Name) {
std::string escapedstr = Base::Tools::escapedUnicodeFromUtf8(constraintName.toUtf8().constData());
Gui::cmdAppObjectArgs(sketch, "renameConstraint(%d, u'%s')",
ConstrNbr, escapedstr.c_str());
}
Gui::Command::commitCommand();
if (sketch->noRecomputes && sketch->ExpressionEngine.depsAreTouched()) {
sketch->ExpressionEngine.execute();
sketch->solve();
}
tryAutoRecompute(sketch);
}
catch (const Base::Exception& e) {
QMessageBox::critical(qApp->activeWindow(), QObject::tr("Dimensional constraint"), QString::fromUtf8(e.what()));
Gui::Command::abortCommand();
tryAutoRecomputeIfNotSolve(sketch);
}
}
}
else {
// command canceled
Gui::Command::abortCommand();
tryAutoRecomputeIfNotSolve(sketch); // we have to update the solver after this aborted addition.
}
}
}
// Utility method to avoid repeating the same code over and over again
void finishDistanceConstraint(Gui::Command* cmd, Sketcher::SketchObject* sketch, bool isDriven=true)
{
@@ -210,7 +109,8 @@ void finishDistanceConstraint(Gui::Command* cmd, Sketcher::SketchObject* sketch,
// Ask for the value of the distance immediately
if (show && isDriven) {
openEditDatumDialog(sketch, ConStr.size() - 1);
EditDatumDialog *editDatumDialog = new EditDatumDialog(sketch, ConStr.size() - 1);
editDatumDialog->exec();
}
else {
// no dialog was shown so commit the command

View File

@@ -39,7 +39,6 @@
#include <Mod/Sketcher/App/SketchObject.h>
#include "ViewProviderSketch.h"
#include "ui_InsertDatum.h"
#include "EditDatumDialog.h"
#include "CommandConstraints.h"
@@ -63,11 +62,11 @@ EditDatumDialog::EditDatumDialog(Sketcher::SketchObject* pcSketch, int ConstrNbr
EditDatumDialog::~EditDatumDialog(){}
void EditDatumDialog::customEvent(QEvent*)
/*void EditDatumDialog::customEvent(QEvent*)
{
this->exec();
this->deleteLater();
}
}*/
void EditDatumDialog::exec(bool atCursor)
{
@@ -83,7 +82,6 @@ void EditDatumDialog::exec(bool atCursor)
Gui::MDIView *mdi = Gui::Application::Instance->activeDocument()->getActiveView();
QDialog dlg(mdi);
Ui::InsertDatum ui_ins_datum;
ui_ins_datum.setupUi(&dlg);
double datum = Constr->getValue();
Base::Quantity init_val;
@@ -119,65 +117,103 @@ void EditDatumDialog::exec(bool atCursor)
ui_ins_datum.labelEdit->setParamGrpPath(QByteArray("User parameter:BaseApp/History/SketcherLength"));
}
//ui_ins_datum.lineEdit->setParamGrpPath("User parameter:History/Sketcher/SetDatum");
init_val.setValue(datum);
// Enable label if we are modifying a driving constraint
ui_ins_datum.labelEdit->setEnabled(Constr->isDriving);
ui_ins_datum.labelEdit->setValue(init_val);
ui_ins_datum.labelEdit->pushToHistory();
ui_ins_datum.labelEdit->selectNumber();
ui_ins_datum.labelEdit->bind(sketch->Constraints.createPath(ConstrNbr));
ui_ins_datum.name->setText(Base::Tools::fromStdString(Constr->Name));
ui_ins_datum.cbDriving->setChecked(! Constr->isDriving);
connect(ui_ins_datum.cbDriving, SIGNAL(toggled(bool)), this, SLOT(drivingToggled(bool)));
connect(ui_ins_datum.labelEdit, SIGNAL(valueChanged(const Base::Quantity&)), this, SLOT(datumChanged()));
connect(ui_ins_datum.labelEdit, SIGNAL(showFormulaDialog(bool)), this, SLOT(formEditorOpened(bool)));
connect(&dlg, SIGNAL(accepted()), this, SLOT(accepted()));
connect(&dlg, SIGNAL(rejected()), this, SLOT(rejected()));
if (atCursor)
dlg.setGeometry(QCursor::pos().x() - dlg.geometry().width() / 2, QCursor::pos().y(), dlg.geometry().width(), dlg.geometry().height());
dlg.exec();
this->deleteLater();
}
}
Gui::Command::openCommand("Modify sketch constraints");
if (dlg.exec()) {
Base::Quantity newQuant = ui_ins_datum.labelEdit->value();
if (newQuant.isQuantity() || (Constr->Type == Sketcher::SnellsLaw && newQuant.isDimensionless())) {
// save the value for the history
ui_ins_datum.labelEdit->pushToHistory();
double newDatum = newQuant.getValue();
try {
if (Constr->isDriving) {
if (ui_ins_datum.labelEdit->hasExpression())
ui_ins_datum.labelEdit->apply();
else
Gui::cmdAppObjectArgs(sketch, "setDatum(%i,App.Units.Quantity('%f %s'))",
ConstrNbr, newDatum, (const char*)newQuant.getUnit().getString().toUtf8());
}
QString constraintName = ui_ins_datum.name->text().trimmed();
if (Base::Tools::toStdString(constraintName) != sketch->Constraints[ConstrNbr]->Name) {
std::string escapedstr = Base::Tools::escapedUnicodeFromUtf8(constraintName.toUtf8().constData());
Gui::cmdAppObjectArgs(sketch, "renameConstraint(%d, u'%s')",
ConstrNbr, escapedstr.c_str());
}
Gui::Command::commitCommand();
if (sketch->noRecomputes && sketch->ExpressionEngine.depsAreTouched()) {
sketch->ExpressionEngine.execute();
sketch->solve();
}
tryAutoRecompute(sketch);
}
catch (const Base::Exception& e) {
QMessageBox::critical(qApp->activeWindow(), QObject::tr("Dimensional constraint"), QString::fromUtf8(e.what()));
Gui::Command::abortCommand();
}
void EditDatumDialog::accepted()
{
Base::Quantity newQuant = ui_ins_datum.labelEdit->value();
if (newQuant.isQuantity() || (Constr->Type == Sketcher::SnellsLaw && newQuant.isDimensionless())) {
// save the value for the history
ui_ins_datum.labelEdit->pushToHistory();
double newDatum = newQuant.getValue();
try {
/*if (ui_ins_datum.cbDriving->isChecked() == Constr->isDriving) {
Gui::cmdAppObjectArgs(sketch, "toggleDriving(%i)", ConstrNbr);
}*/
if (! ui_ins_datum.cbDriving->isChecked()) {
if (ui_ins_datum.labelEdit->hasExpression())
ui_ins_datum.labelEdit->apply();
else
Gui::cmdAppObjectArgs(sketch, "setDatum(%i,App.Units.Quantity('%f %s'))",
ConstrNbr, newDatum, (const char*)newQuant.getUnit().getString().toUtf8());
}
} else {
QString constraintName = ui_ins_datum.name->text().trimmed();
if (Base::Tools::toStdString(constraintName) != sketch->Constraints[ConstrNbr]->Name) {
std::string escapedstr = Base::Tools::escapedUnicodeFromUtf8(constraintName.toUtf8().constData());
Gui::cmdAppObjectArgs(sketch, "renameConstraint(%d, u'%s')",
ConstrNbr, escapedstr.c_str());
}
Gui::Command::commitCommand();
if (sketch->noRecomputes && sketch->ExpressionEngine.depsAreTouched()) {
sketch->ExpressionEngine.execute();
sketch->solve();
}
tryAutoRecompute(sketch);
}
catch (const Base::Exception& e) {
QMessageBox::critical(qApp->activeWindow(), QObject::tr("Dimensional constraint"), QString::fromUtf8(e.what()));
Gui::Command::abortCommand();
}
}
}
void EditDatumDialog::rejected()
{
Gui::Command::abortCommand();
}
void EditDatumDialog::drivingToggled(bool state)
{
if (state)
{
ui_ins_datum.labelEdit->setToLastUsedValue();
}
sketch->setDriving(ConstrNbr, !state);
}
void EditDatumDialog::datumChanged()
{
if (ui_ins_datum.labelEdit->text() != ui_ins_datum.labelEdit->getHistory()[0]) {
ui_ins_datum.cbDriving->setChecked(false);
}
}
void EditDatumDialog::formEditorOpened(bool state)
{
if(state)
{
ui_ins_datum.cbDriving->setChecked(false);
}
}
#include "moc_EditDatumDialog.cpp"

View File

@@ -23,6 +23,7 @@
#define SKETCHERGUI_EditDatumDialog_H
#include <QObject>
#include "ui_InsertDatum.h"
namespace Sketcher {
class Constraint;
@@ -33,19 +34,28 @@ namespace SketcherGui {
class ViewProviderSketch;
class EditDatumDialog : public QObject {
Q_DECLARE_TR_FUNCTIONS(SketcherGui::EditDatumDialog)
Q_OBJECT
public:
EditDatumDialog(ViewProviderSketch* vp, int ConstrNbr);
EditDatumDialog(Sketcher::SketchObject* pcSketch, int ConstrNbr);
~EditDatumDialog();
void exec(bool atCursor=true);
void customEvent(QEvent*);
//void customEvent(QEvent*);
private:
Sketcher::SketchObject* sketch;
Sketcher::Constraint* Constr;
int ConstrNbr;
Ui::InsertDatum ui_ins_datum;
private Q_SLOTS:
void accepted();
void rejected();
void drivingToggled(bool);
void datumChanged();
void formEditorOpened(bool);
};
}

View File

@@ -9,10 +9,16 @@
<rect>
<x>0</x>
<y>0</y>
<width>344</width>
<height>122</height>
<width>254</width>
<height>140</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="windowTitle">
<string>Insert datum</string>
</property>
@@ -29,11 +35,17 @@
<item row="0" column="1">
<widget class="Gui::PrefQuantitySpinBox" name="labelEdit" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>20</height>
</size>
</property>
</widget>
</item>
<item row="1" column="0">
@@ -44,22 +56,41 @@
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="name"/>
<widget class="QLineEdit" name="name">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>20</height>
</size>
</property>
<property name="toolTip">
<string>Constraint name (available for expressions)</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
<widget class="QCheckBox" name="cbDriving">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
<property name="toolTip">
<string>Reference (or constraint) dimension</string>
</property>
</spacer>
<property name="text">
<string>Reference</string>
</property>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">

View File

@@ -1022,14 +1022,11 @@ void ViewProviderSketch::editDoubleClicked(void)
// if its the right constraint
if (Constr->isDimensional()) {
if(!Constr->isDriving) {
Gui::cmdAppObjectArgs(getObject(), "setDriving(%i,%s)", id, "True");
}
// Coin's SoIdleSensor causes problems on some platform while Qt seems to work properly (#0001517)
Gui::Command::openCommand("Modify sketch constraints");
EditDatumDialog *editDatumDialog = new EditDatumDialog(this, id);
QCoreApplication::postEvent(editDatumDialog, new QEvent(QEvent::User));
//QCoreApplication::postEvent(editDatumDialog, new QEvent(QEvent::User));
editDatumDialog->exec();
edit->editDatumDialog = true; // avoid to double handle "ESC"
}
}