1
/***************************************************************************
2
* Copyright (c) 2021 Uwe Stöhr <uwestoehr@lyx.org> *
4
* This file is part of the FreeCAD CAx development system. *
6
* This library is free software; you can redistribute it and/or *
7
* modify it under the terms of the GNU Library General Public *
8
* License as published by the Free Software Foundation; either *
9
* version 2 of the License, or (at your option) any later version. *
11
* This library is distributed in the hope that it will be useful, *
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14
* GNU Library General Public License for more details. *
16
* You should have received a copy of the GNU Library General Public *
17
* License along with this library; see the file COPYING.LIB. If not, *
18
* write to the Free Software Foundation, Inc., 59 Temple Place, *
19
* Suite 330, Boston, MA 02111-1307, USA *
21
***************************************************************************/
23
#include "PreCompiled.h"
26
# include <QMessageBox>
27
#endif // #ifndef _PreComp_
29
#include <App/Document.h>
30
#include <Gui/BitmapFactory.h>
31
#include <Gui/Command.h>
32
#include <Gui/Document.h>
33
#include <Gui/MainWindow.h>
34
#include <Gui/Selection.h>
35
#include <Gui/SelectionObject.h>
36
#include <Mod/TechDraw/App/DrawUtil.h>
37
#include <Mod/TechDraw/App/DrawViewPart.h>
39
#include "ui_TaskDimension.h"
40
#include "TaskDimension.h"
41
#include "QGIViewDimension.h"
42
#include "ViewProviderDimension.h"
46
using namespace TechDraw;
47
using namespace TechDrawGui;
49
TaskDimension::TaskDimension(QGIViewDimension *parent, ViewProviderDimension *dimensionVP) :
50
ui(new Ui_TaskDimension),
52
m_dimensionVP(dimensionVP)
57
ui->cbTheoreticallyExact->setChecked(parent->getDimFeat()->TheoreticalExact.getValue());
58
connect(ui->cbTheoreticallyExact, &QCheckBox::stateChanged, this, &TaskDimension::onTheoreticallyExactChanged);
59
// if TheoreticalExact disable tolerances
60
if (parent->getDimFeat()->TheoreticalExact.getValue()) {
61
ui->cbEqualTolerance->setDisabled(true);
62
ui->qsbOvertolerance->setDisabled(true);
63
ui->qsbUndertolerance->setDisabled(true);
64
ui->leFormatSpecifierOverTolerance->setDisabled(true);
65
ui->leFormatSpecifierUnderTolerance->setDisabled(true);
67
ui->cbEqualTolerance->setChecked(parent->getDimFeat()->EqualTolerance.getValue());
68
connect(ui->cbEqualTolerance, &QCheckBox::stateChanged, this, &TaskDimension::onEqualToleranceChanged);
69
// if EqualTolerance overtolernace must not be negative
70
if (parent->getDimFeat()->EqualTolerance.getValue())
71
ui->qsbOvertolerance->setMinimum(0.0);
72
if ((parent->getDimFeat()->Type.isValue("Angle")) ||
73
(parent->getDimFeat()->Type.isValue("Angle3Pt"))) {
74
ui->qsbOvertolerance->setUnit(Base::Unit::Angle);
75
ui->qsbUndertolerance->setUnit(Base::Unit::Angle);
78
ui->qsbOvertolerance->setUnit(Base::Unit::Length);
79
ui->qsbUndertolerance->setUnit(Base::Unit::Length);
81
ui->qsbOvertolerance->setValue(parent->getDimFeat()->OverTolerance.getValue());
82
ui->qsbUndertolerance->setValue(parent->getDimFeat()->UnderTolerance.getValue());
83
connect(ui->qsbOvertolerance, qOverload<double>(&QuantitySpinBox::valueChanged), this, &TaskDimension::onOvertoleranceChanged);
84
connect(ui->qsbUndertolerance, qOverload<double>(&QuantitySpinBox::valueChanged), this, &TaskDimension::onUndertoleranceChanged);
85
// undertolerance is disabled when EqualTolerance is true
86
if (ui->cbEqualTolerance->isChecked()) {
87
ui->qsbUndertolerance->setDisabled(true);
88
ui->leFormatSpecifierUnderTolerance->setDisabled(true);
92
std::string StringValue = parent->getDimFeat()->FormatSpec.getValue();
93
QString qs = QString::fromUtf8(StringValue.data(), StringValue.size());
94
ui->leFormatSpecifier->setText(qs);
95
connect(ui->leFormatSpecifier, &QLineEdit::textChanged, this, &TaskDimension::onFormatSpecifierChanged);
96
ui->cbArbitrary->setChecked(parent->getDimFeat()->Arbitrary.getValue());
97
connect(ui->cbArbitrary, &QCheckBox::stateChanged, this, &TaskDimension::onArbitraryChanged);
98
StringValue = parent->getDimFeat()->FormatSpecOverTolerance.getValue();
99
qs = QString::fromUtf8(StringValue.data(), StringValue.size());
100
ui->leFormatSpecifierOverTolerance->setText(qs);
101
StringValue = parent->getDimFeat()->FormatSpecUnderTolerance.getValue();
102
qs = QString::fromUtf8(StringValue.data(), StringValue.size());
103
ui->leFormatSpecifierUnderTolerance->setText(qs);
104
connect(ui->leFormatSpecifierOverTolerance, &QLineEdit::textChanged, this, &TaskDimension::onFormatSpecifierOverToleranceChanged);
105
connect(ui->leFormatSpecifierUnderTolerance, &QLineEdit::textChanged, this, &TaskDimension::onFormatSpecifierUnderToleranceChanged);
106
ui->cbArbitraryTolerances->setChecked(parent->getDimFeat()->ArbitraryTolerances.getValue());
107
connect(ui->cbArbitraryTolerances, &QCheckBox::stateChanged, this, &TaskDimension::onArbitraryTolerancesChanged);
111
ui->cbArrowheads->setChecked(dimensionVP->FlipArrowheads.getValue());
112
connect(ui->cbArrowheads, &QCheckBox::stateChanged, this, &TaskDimension::onFlipArrowheadsChanged);
113
ui->dimensionColor->setColor(dimensionVP->Color.getValue().asValue<QColor>());
114
connect(ui->dimensionColor, &ColorButton::changed, this, &TaskDimension::onColorChanged);
115
ui->qsbFontSize->setValue(dimensionVP->Fontsize.getValue());
116
ui->qsbFontSize->setUnit(Base::Unit::Length);
117
ui->qsbFontSize->setMinimum(0);
118
connect(ui->qsbFontSize, qOverload<double>(&QuantitySpinBox::valueChanged), this, &TaskDimension::onFontsizeChanged);
119
ui->comboDrawingStyle->setCurrentIndex(dimensionVP->StandardAndStyle.getValue());
120
connect(ui->comboDrawingStyle, qOverload<int>(&QComboBox::currentIndexChanged), this, &TaskDimension::onDrawingStyleChanged);
124
ui->rbOverride->setChecked(parent->getDimFeat()->AngleOverride.getValue());
125
connect(ui->rbOverride, &QRadioButton::toggled, this, &TaskDimension::onOverrideToggled);
126
ui->dsbDimAngle->setValue(parent->getDimFeat()->LineAngle.getValue());
127
connect(ui->dsbDimAngle, qOverload<double>(&QDoubleSpinBox::valueChanged), this, &TaskDimension::onDimAngleChanged);
128
ui->dsbExtAngle->setValue(parent->getDimFeat()->ExtensionAngle.getValue());
129
connect(ui->dsbExtAngle, qOverload<double>(&QDoubleSpinBox::valueChanged), this, &TaskDimension::onExtAngleChanged);
130
connect(ui->pbDimUseDefault, &QPushButton::clicked, this, &TaskDimension::onDimUseDefaultClicked);
131
connect(ui->pbDimUseSelection, &QPushButton::clicked, this, &TaskDimension::onDimUseSelectionClicked);
132
connect(ui->pbExtUseDefault, &QPushButton::clicked, this, &TaskDimension::onExtUseDefaultClicked);
133
connect(ui->pbExtUseSelection, &QPushButton::clicked, this, &TaskDimension::onExtUseSelectionClicked);
135
Gui::Document* doc = m_dimensionVP->getDocument();
136
doc->openCommand("TaskDimension");
139
TaskDimension::~TaskDimension()
143
bool TaskDimension::accept()
145
if (m_dimensionVP.expired()) {
146
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Missing Dimension"),
147
QObject::tr("Dimension not found. Was it deleted? Can not continue."));
150
Gui::Document* doc = m_dimensionVP->getDocument();
151
m_dimensionVP->getObject()->purgeTouched();
152
doc->commitCommand();
158
bool TaskDimension::reject()
160
if (m_dimensionVP.expired()) {
161
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Missing Dimension"),
162
QObject::tr("Dimension not found. Was it deleted? Can not continue."));
165
Gui::Document* doc = m_dimensionVP->getDocument();
168
m_parent->updateView(true);
169
m_dimensionVP->getObject()->purgeTouched();
175
void TaskDimension::recomputeFeature()
177
if (m_dimensionVP.expired()) {
178
// guard against deletion while this dialog is running
181
App::DocumentObject* objVP = m_dimensionVP->getObject();
183
objVP->getDocument()->recomputeFeature(objVP);
186
void TaskDimension::onTheoreticallyExactChanged()
188
m_parent->getDimFeat()->TheoreticalExact.setValue(ui->cbTheoreticallyExact->isChecked());
189
// if TheoreticalExact disable tolerances and set them to zero
190
if (ui->cbTheoreticallyExact->isChecked()) {
191
ui->qsbOvertolerance->setValue(0.0);
192
ui->qsbUndertolerance->setValue(0.0);
193
ui->cbEqualTolerance->setDisabled(true);
194
ui->qsbOvertolerance->setDisabled(true);
195
ui->qsbUndertolerance->setDisabled(true);
196
ui->leFormatSpecifierOverTolerance->setDisabled(true);
197
ui->leFormatSpecifierUnderTolerance->setDisabled(true);
198
ui->cbArbitraryTolerances->setDisabled(true);
199
ui->cbArbitraryTolerances->setChecked(false);
202
ui->cbEqualTolerance->setDisabled(false);
203
ui->qsbOvertolerance->setDisabled(false);
204
ui->leFormatSpecifierOverTolerance->setDisabled(false);
205
ui->cbArbitraryTolerances->setDisabled(false);
206
if (!ui->cbEqualTolerance->isChecked()) {
207
ui->qsbUndertolerance->setDisabled(false);
208
ui->leFormatSpecifierUnderTolerance->setDisabled(false);
214
void TaskDimension::onEqualToleranceChanged()
216
m_parent->getDimFeat()->EqualTolerance.setValue(ui->cbEqualTolerance->isChecked());
217
// if EqualTolerance set negated overtolerance for untertolerance
218
// then also the OverTolerance must be positive
219
if (ui->cbEqualTolerance->isChecked()) {
220
// if OverTolerance is negative or zero, first set it to zero
221
if (ui->qsbOvertolerance->value().getValue() < 0)
222
ui->qsbOvertolerance->setValue(0.0);
223
ui->qsbOvertolerance->setMinimum(0.0);
224
ui->qsbUndertolerance->setValue(-1.0 * ui->qsbOvertolerance->value().getValue());
225
ui->qsbUndertolerance->setUnit(ui->qsbOvertolerance->value().getUnit());
226
ui->qsbUndertolerance->setDisabled(true);
227
ui->leFormatSpecifierUnderTolerance->setDisabled(true);
230
ui->qsbOvertolerance->setMinimum(-DBL_MAX);
231
if (!ui->cbTheoreticallyExact->isChecked()) {
232
ui->qsbUndertolerance->setDisabled(false);
233
ui->leFormatSpecifierUnderTolerance->setDisabled(false);
239
void TaskDimension::onOvertoleranceChanged()
241
m_parent->getDimFeat()->OverTolerance.setValue(ui->qsbOvertolerance->value().getValue());
242
// if EqualTolerance set negated overtolerance for untertolerance
243
if (ui->cbEqualTolerance->isChecked()) {
244
ui->qsbUndertolerance->setValue(-1.0 * ui->qsbOvertolerance->value().getValue());
245
ui->qsbUndertolerance->setUnit(ui->qsbOvertolerance->value().getUnit());
250
void TaskDimension::onUndertoleranceChanged()
252
m_parent->getDimFeat()->UnderTolerance.setValue(ui->qsbUndertolerance->value().getValue());
256
void TaskDimension::onFormatSpecifierChanged()
258
m_parent->getDimFeat()->FormatSpec.setValue(ui->leFormatSpecifier->text().toUtf8().constData());
262
void TaskDimension::onArbitraryChanged()
264
m_parent->getDimFeat()->Arbitrary.setValue(ui->cbArbitrary->isChecked());
268
void TaskDimension::onFormatSpecifierOverToleranceChanged()
270
// Base::Console().Message("TD::onFormatSpecifierOverToleranceChanged()\n");
271
// if (m_blockToleranceLoop) { return; }
272
m_parent->getDimFeat()->FormatSpecOverTolerance.setValue(ui->leFormatSpecifierOverTolerance->text().toUtf8().constData());
273
if (ui->cbArbitraryTolerances->isChecked() ) {
274
// Don't do anything else if tolerance is Arbitrary
279
if (ui->cbEqualTolerance->isChecked()) {
280
// the under tolerance has to match this one
281
ui->leFormatSpecifierUnderTolerance->setText(ui->leFormatSpecifierOverTolerance->text());
282
m_parent->getDimFeat()->FormatSpecUnderTolerance.setValue(ui->leFormatSpecifierUnderTolerance->text().toUtf8().constData());
287
void TaskDimension::onFormatSpecifierUnderToleranceChanged()
289
// Base::Console().Message("TD::onFormatSpecifierUnderToleranceChanged()\n");
290
m_parent->getDimFeat()->FormatSpecUnderTolerance.setValue(ui->leFormatSpecifierUnderTolerance->text().toUtf8().constData());
291
if (ui->cbArbitraryTolerances->isChecked() ) {
292
// Don't do anything else if tolerance is Arbitrary
296
if (ui->cbEqualTolerance->isChecked()) {
297
// if EqualTolerance is checked, then underTolerance is disabled, so this shouldn't happen!
298
// the over tolerance has to match this one
299
ui->leFormatSpecifierOverTolerance->setText(ui->leFormatSpecifierUnderTolerance->text());
300
m_parent->getDimFeat()->FormatSpecOverTolerance.setValue(ui->leFormatSpecifierOverTolerance->text().toUtf8().constData());
305
void TaskDimension::onArbitraryTolerancesChanged()
307
m_parent->getDimFeat()->ArbitraryTolerances.setValue(ui->cbArbitraryTolerances->isChecked());
311
void TaskDimension::onFlipArrowheadsChanged()
313
if (m_dimensionVP.expired()) {
316
m_dimensionVP->FlipArrowheads.setValue(ui->cbArrowheads->isChecked());
320
void TaskDimension::onColorChanged()
322
if (m_dimensionVP.expired()) {
326
ac.setValue<QColor>(ui->dimensionColor->color());
327
m_dimensionVP->Color.setValue(ac);
331
void TaskDimension::onFontsizeChanged()
333
if (m_dimensionVP.expired()) {
336
m_dimensionVP->Fontsize.setValue(ui->qsbFontSize->value().getValue());
340
void TaskDimension::onDrawingStyleChanged()
342
if (m_dimensionVP.expired()) {
345
m_dimensionVP->StandardAndStyle.setValue(ui->comboDrawingStyle->currentIndex());
349
void TaskDimension::onOverrideToggled()
351
m_parent->getDimFeat()->AngleOverride.setValue(ui->rbOverride->isChecked());
356
void TaskDimension::onDimAngleChanged()
358
m_parent->getDimFeat()->LineAngle.setValue(ui->dsbDimAngle->value());
362
void TaskDimension::onExtAngleChanged()
364
m_parent->getDimFeat()->ExtensionAngle.setValue(ui->dsbExtAngle->value());
368
void TaskDimension::onDimUseDefaultClicked()
370
pointPair points = m_parent->getDimFeat()->getLinearPoints();
371
//duplicate coordinate conversion logic from QGIViewDimension
372
Base::Vector2d first2(points.first().x, -points.first().y);
373
Base::Vector2d second2(points.second().x, -points.second().y);
374
double lineAngle = (second2 - first2).Angle();
375
ui->dsbDimAngle->setValue(lineAngle * 180.0 / M_PI);
378
void TaskDimension::onDimUseSelectionClicked()
380
std::pair<double, bool> result = getAngleFromSelection();
382
ui->dsbDimAngle->setValue(result.first * 180.0 / M_PI);
386
void TaskDimension::onExtUseDefaultClicked()
388
pointPair points = m_parent->getDimFeat()->getLinearPoints();
389
//duplicate coordinate conversion logic from QGIViewDimension
390
Base::Vector2d first2(points.first().x, -points.first().y);
391
Base::Vector2d second2(points.second().x, -points.second().y);
392
Base::Vector2d lineDirection = second2 - first2;
393
Base::Vector2d extensionDirection(-lineDirection.y, lineDirection.x);
394
double extensionAngle = extensionDirection.Angle();
395
ui->dsbExtAngle->setValue(extensionAngle * 180.0 / M_PI);
397
void TaskDimension::onExtUseSelectionClicked()
399
std::pair<double, bool> result = getAngleFromSelection();
401
ui->dsbExtAngle->setValue(result.first * 180.0 / M_PI);
405
std::pair<double, bool> TaskDimension::getAngleFromSelection()
407
std::pair<double, bool> result;
409
result.second = true;
410
std::vector<Gui::SelectionObject> selection = Gui::Selection().getSelectionEx();
411
TechDraw::DrawViewPart * objFeat = nullptr;
412
std::vector<std::string> SubNames;
413
if (!selection.empty()) {
414
objFeat = static_cast<TechDraw::DrawViewPart*> (selection.front().getObject());
415
SubNames = selection.front().getSubNames();
416
if (SubNames.size() == 2) { //expecting Vertices
417
std::string geomName0 = DrawUtil::getGeomTypeFromName(SubNames[0]);
418
int geomIndex0 = DrawUtil::getIndexFromName(SubNames[0]);
419
std::string geomName1 = DrawUtil::getGeomTypeFromName(SubNames[1]);
420
int geomIndex1 = DrawUtil::getIndexFromName(SubNames[1]);
421
if ((geomName0 == "Vertex") && (geomName1 == "Vertex")) {
422
TechDraw::VertexPtr v0 = objFeat->getProjVertexByIndex(geomIndex0);
423
TechDraw::VertexPtr v1 = objFeat->getProjVertexByIndex(geomIndex1);
424
Base::Vector2d v02(v0->point().x, -v0->point().y);
425
Base::Vector2d v12(v1->point().x, -v1->point().y);
426
result.first = (v12 - v02).Angle();
429
} else if (SubNames.size() == 1) { //expecting Edge
430
std::string geomName0 = DrawUtil::getGeomTypeFromName(SubNames[0]);
431
int geomIndex0 = DrawUtil::getIndexFromName(SubNames[0]);
432
if (geomName0 == "Edge") {
433
TechDraw::BaseGeomPtr edge = objFeat->getGeomByIndex(geomIndex0);
434
Base::Vector2d v02(edge->getStartPoint().x, -edge->getStartPoint().y);
435
Base::Vector2d v12(edge->getEndPoint().x, -edge->getEndPoint().y);
436
result.first = (v12 - v02).Angle();
442
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Incorrect Selection"),
443
QObject::tr("Select 2 Vertexes or 1 Edge"));
444
result.second = false;
448
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
449
TaskDlgDimension::TaskDlgDimension(QGIViewDimension *parent, ViewProviderDimension *dimensionVP) :
452
widget = new TaskDimension(parent, dimensionVP);
453
taskbox = new Gui::TaskView::TaskBox(Gui::BitmapFactory().pixmap("TechDraw_Dimension"), widget->windowTitle(), true, nullptr);
454
taskbox->groupLayout()->addWidget(widget);
455
Content.push_back(taskbox);
456
setAutoCloseOnTransactionChange(true);
459
TaskDlgDimension::~TaskDlgDimension()
463
void TaskDlgDimension::update()
467
//==== calls from the TaskView ===============================================================
468
void TaskDlgDimension::open()
472
void TaskDlgDimension::clicked(int i)
477
bool TaskDlgDimension::accept()
483
bool TaskDlgDimension::reject()
489
#include "moc_TaskDimension.cpp"