Seamly2D
Code documentation
intersect_circletangent_dialog.cpp
Go to the documentation of this file.
1 /**************************************************************************
2  **
3  ** @file intersect_circletangent_dialog.cpp
4  ** @author Roman Telezhynskyi <dismine(at)gmail.com>
5  ** @date 3 6, 2015
6  **
7  ** @author Douglas S. Caskey
8  ** @date 7.16.2022
9  **
10  ** @copyright
11  ** Copyright (C) 2013-2022 Seamly2D project.
12  ** This source code is part of the Seamly2D project, a pattern making
13  ** program, whose allow create and modeling patterns of clothing.
14  **
15  ** <https://github.com/fashionfreedom/seamly2d> All Rights Reserved.
16  **
17  ** Seamly2D is free software: you can redistribute it and/or modify
18  ** it under the terms of the GNU General Public License as published
19  ** by the Free Software Foundation, either version 3 of the License,
20  ** or (at your option) any later version.
21  **
22  ** Seamly2D is distributed in the hope that it will be useful,
23  ** but WITHOUT ANY WARRANTY; without even the implied warranty of
24  ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25  ** GNU General Public License for more details.
26  **
27  ** You should have received a copy of the GNU General Public License
28  ** along with Seamly2D. If not, see <http://www.gnu.org/licenses/>.
29  **
30  *************************************************************************/
31 
33 #include "ui_intersect_circletangent_dialog.h"
34 
35 #include "../ifc/xml/vdomdocument.h"
36 #include "../support/edit_formula_dialog.h"
37 #include "../vmisc/vabstractapplication.h"
38 #include "../vmisc/vcommonsettings.h"
39 #include "../vpatterndb/vtranslatevars.h"
40 #include "../../visualization/visualization.h"
41 #include "../../visualization/line/intersect_circletangent_visual.h"
42 
43 #include <limits.h>
44 #include <QColor>
45 #include <QComboBox>
46 #include <QDialog>
47 #include <QLabel>
48 #include <QLineEdit>
49 #include <QPlainTextEdit>
50 #include <QPointer>
51 #include <QPushButton>
52 #include <QTimer>
53 #include <QToolButton>
54 #include <Qt>
55 
56 //---------------------------------------------------------------------------------------------------------------------
58  QWidget *parent)
59  : DialogTool(data, toolId, parent)
61  , flagCircleRadius(false)
62  , timerCircleRadius(nullptr)
63  , circleRadius()
64  , formulaBaseHeightCircleRadius(0)
65 {
66  ui->setupUi(this);
67  setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
68  setWindowIcon(QIcon(":/toolicon/32x32/point_from_circle_and_tangent.png"));
69 
70  ui->lineEditNamePoint->setClearButtonEnabled(true);
71 
72  ui->lineEditNamePoint->setText(qApp->getCurrentDocument()->GenerateLabel(LabelType::NewLabel));
73  labelEditNamePoint = ui->labelEditNamePoint;
74 
75  plainTextEditFormula = ui->plainTextEditRadius;
76  this->formulaBaseHeightCircleRadius = ui->plainTextEditRadius->height();
77 
78  ui->plainTextEditRadius->installEventFilter(this);
79 
80  timerCircleRadius = new QTimer(this);
81  connect(timerCircleRadius, &QTimer::timeout, this, &IntersectCircleTangentDialog::EvalCircleRadius);
82 
84  CheckState();
85 
86  FillComboBoxPoints(ui->comboBoxCircleCenter);
87  FillComboBoxPoints(ui->comboBoxTangentPoint);
88  FillComboBoxCrossCirclesPoints(ui->comboBoxResult);
89 
90  connect(ui->lineEditNamePoint, &QLineEdit::textChanged,
92 
93  connect(ui->comboBoxCircleCenter, &QComboBox::currentTextChanged,
95 
96  connect(ui->toolButtonExprRadius, &QPushButton::clicked,
98 
99  connect(ui->plainTextEditRadius, &QPlainTextEdit::textChanged, this,
101 
102  connect(ui->pushButtonGrowRadius, &QPushButton::clicked, this,
104 
106 }
107 
108 //---------------------------------------------------------------------------------------------------------------------
110 {
111  delete ui;
112 }
113 
114 //---------------------------------------------------------------------------------------------------------------------
116 {
117  pointName = value;
118  ui->lineEditNamePoint->setText(pointName);
119 }
120 
121 //---------------------------------------------------------------------------------------------------------------------
123 {
124  return getCurrentObjectId(ui->comboBoxCircleCenter);
125 }
126 
127 //---------------------------------------------------------------------------------------------------------------------
129 {
130  setCurrentPointId(ui->comboBoxCircleCenter, value);
131 
132  IntersectCircleTangentVisual *point = qobject_cast<IntersectCircleTangentVisual *>(vis);
133  SCASSERT(point != nullptr)
134  point->setObject2Id(value);
135 }
136 
137 //---------------------------------------------------------------------------------------------------------------------
139 {
140  return qApp->TrVars()->TryFormulaFromUser(ui->plainTextEditRadius->toPlainText(),
141  qApp->Settings()->GetOsSeparator());
142 }
143 
144 //---------------------------------------------------------------------------------------------------------------------
146 {
147  const QString formula = qApp->TrVars()->FormulaToUser(value, qApp->Settings()->GetOsSeparator());
148  // increase height if needed.
149  if (formula.length() > 80)
150  {
152  }
153  ui->plainTextEditRadius->setPlainText(formula);
154 
155  IntersectCircleTangentVisual *point = qobject_cast<IntersectCircleTangentVisual *>(vis);
156  SCASSERT(point != nullptr)
157  point->setCRadius(formula);
158 
159  MoveCursorToEnd(ui->plainTextEditRadius);
160 }
161 
162 //---------------------------------------------------------------------------------------------------------------------
164 {
165  return getCurrentObjectId(ui->comboBoxTangentPoint);
166 }
167 
168 //---------------------------------------------------------------------------------------------------------------------
170 {
171  setCurrentPointId(ui->comboBoxTangentPoint, value);
172 
173  IntersectCircleTangentVisual *point = qobject_cast<IntersectCircleTangentVisual *>(vis);
174  SCASSERT(point != nullptr)
175  point->setObject1Id(value);
176 }
177 
178 //---------------------------------------------------------------------------------------------------------------------
180 {
181  return getCurrentCrossPoint<CrossCirclesPoint>(ui->comboBoxResult);
182 }
183 
184 //---------------------------------------------------------------------------------------------------------------------
186 {
187  const qint32 index = ui->comboBoxResult->findData(static_cast<int>(p));
188  if (index != -1)
189  {
190  ui->comboBoxResult->setCurrentIndex(index);
191 
192  IntersectCircleTangentVisual *point = qobject_cast<IntersectCircleTangentVisual *>(vis);
193  SCASSERT(point != nullptr)
194  point->setCrossPoint(p);
195  }
196 }
197 
198 //---------------------------------------------------------------------------------------------------------------------
200 {
201  if (prepare == false)// After first choose we ignore all objects
202  {
203  if (type == SceneObject::Point)
204  {
205  IntersectCircleTangentVisual *point = qobject_cast<IntersectCircleTangentVisual *>(vis);
206  SCASSERT(point != nullptr)
207 
208  switch (number)
209  {
210  case 0:
211  if (SetObject(id, ui->comboBoxTangentPoint, tr("Select a circle center")))
212  {
213  number++;
214  point->VisualMode(id);
215  }
216  break;
217  case 1:
218  if (getCurrentObjectId(ui->comboBoxTangentPoint) != id)
219  {
220  if (SetObject(id, ui->comboBoxCircleCenter, ""))
221  {
222  number = 0;
223  point->setObject2Id(id);
224  point->RefreshGeometry();
225  prepare = true;
226  this->setModal(true);
227  this->show();
228  }
229  }
230  break;
231  default:
232  break;
233  }
234  }
235  }
236 }
237 
238 //---------------------------------------------------------------------------------------------------------------------
240 {
241  QColor color = okColor;
242  if (getCurrentObjectId(ui->comboBoxCircleCenter) == getCurrentObjectId(ui->comboBoxTangentPoint))
243  {
244  flagError = false;
245  color = errorColor;
246  }
247  else
248  {
249  flagError = true;
250  color = okColor;
251  }
252  ChangeColor(ui->labelCircleCenter, color);
253  ChangeColor(ui->labelTangentPoint, color);
254  CheckState();
255 }
256 
257 //---------------------------------------------------------------------------------------------------------------------
259 {
260  DeployFormula(ui->plainTextEditRadius, ui->pushButtonGrowRadius, formulaBaseHeightCircleRadius);
261 }
262 
263 //---------------------------------------------------------------------------------------------------------------------
265 {
266  labelEditFormula = ui->labelEditRadius;
267  labelResultCalculation = ui->labelResultCircleRadius;
268  const QString postfix = UnitsToStr(qApp->patternUnit(), true);
269  ValFormulaChanged(flagCircleRadius, ui->plainTextEditRadius, timerCircleRadius, postfix);
270 }
271 
272 //---------------------------------------------------------------------------------------------------------------------
274 {
275  EditFormulaDialog *dialog = new EditFormulaDialog(data, toolId, this);
276  dialog->setWindowTitle(tr("Edit radius"));
277  dialog->SetFormula(GetCircleRadius());
278  dialog->setPostfix(UnitsToStr(qApp->patternUnit(), true));
279  if (dialog->exec() == QDialog::Accepted)
280  {
281  SetCircleRadius(dialog->GetFormula());
282  }
283  delete dialog;
284 }
285 
286 //---------------------------------------------------------------------------------------------------------------------
288 {
289  labelEditFormula = ui->labelEditRadius;
290  const QString postfix = UnitsToStr(qApp->patternUnit(), true);
291  const qreal radius = Eval(ui->plainTextEditRadius->toPlainText(), flagCircleRadius,
292  ui->labelResultCircleRadius, postfix);
293 
294  if (radius < 0)
295  {
296  flagCircleRadius = false;
297  ChangeColor(labelEditFormula, Qt::red);
298  ui->labelResultCircleRadius->setText(tr("Error"));
299  ui->labelResultCircleRadius->setToolTip(tr("Radius can't be negative"));
300 
302  }
303 }
304 
305 //---------------------------------------------------------------------------------------------------------------------
307 {
308  AddVisualization<IntersectCircleTangentVisual>();
309 }
310 
311 //---------------------------------------------------------------------------------------------------------------------
313 {
314  pointName = ui->lineEditNamePoint->text();
315 
316  QString radius = ui->plainTextEditRadius->toPlainText();
317  radius.replace("\n", " ");
318 
319  IntersectCircleTangentVisual *point = qobject_cast<IntersectCircleTangentVisual *>(vis);
320  SCASSERT(point != nullptr)
321 
324  point->setCRadius(radius);
326  point->RefreshGeometry();
327 }
328 
329 //---------------------------------------------------------------------------------------------------------------------
331 {
332  ui->plainTextEditRadius->blockSignals(true);
333  DialogTool::closeEvent(event);
334 }
335 
336 //---------------------------------------------------------------------------------------------------------------------
338 {
339  SCASSERT(ok_Button != nullptr)
341  // In case dialog hasn't apply button
342  if (apply_Button != nullptr)
343  {
344  apply_Button->setEnabled(ok_Button->isEnabled());
345  }
346 }
The DialogTool class parent for all dialog of tools.
Definition: dialogtool.h:107
void setCurrentPointId(QComboBox *box, const quint32 &value, FillComboBox rule=FillComboBox::NoChildren, const quint32 &ch1=NULL_ID, const quint32 &ch2=NULL_ID) const
Definition: dialogtool.cpp:896
const QColor okColor
Definition: dialogtool.h:219
void FillComboBoxPoints(QComboBox *box, FillComboBox rule=FillComboBox::Whole, const quint32 &ch1=NULL_ID, const quint32 &ch2=NULL_ID) const
FillComboBoxPoints fill comboBox list of points.
Definition: dialogtool.cpp:242
void NamePointChanged()
NamePointChanged check name of point.
bool flagName
flagName true if name is correct
Definition: dialogtool.h:183
void FillComboBoxCrossCirclesPoints(QComboBox *box) const
Definition: dialogtool.cpp:373
void MoveCursorToEnd(QPlainTextEdit *plainTextEdit) const
Definition: dialogtool.cpp:432
QPushButton * ok_Button
ok_Button button ok
Definition: dialogtool.h:199
bool flagFormula
flagFormula true if formula correct
Definition: dialogtool.h:186
QString pointName
pointName name of point
Definition: dialogtool.h:231
qreal Eval(const QString &text, bool &flag, QLabel *label, const QString &postfix, bool checkZero=true, bool checkLessThanZero=false)
Eval evaluate formula and show result.
Definition: dialogtool.cpp:805
const QColor errorColor
Definition: dialogtool.h:220
qint32 number
number number of handled objects
Definition: dialogtool.h:234
virtual void closeEvent(QCloseEvent *event) Q_DECL_OVERRIDE
closeEvent handle when dialog cloded
Definition: dialogtool.cpp:192
void ValFormulaChanged(bool &flag, QLineEdit *edit, QTimer *timer, const QString &postfix=QString())
ValFormulaChanged handle change formula.
Definition: dialogtool.cpp:744
bool SetObject(const quint32 &id, QComboBox *box, const QString &toolTip)
Definition: dialogtool.cpp:974
QPushButton * apply_Button
apply_Button button apply
Definition: dialogtool.h:202
QLabel * labelEditNamePoint
labelEditNamePoint label used when need show wrong name of point
Definition: dialogtool.h:214
quint32 toolId
Definition: dialogtool.h:225
QLabel * labelEditFormula
labelEditFormula label used when need show wrong formula
Definition: dialogtool.h:217
void initializeOkCancelApply(T *ui)
initializeOkCancelApply initialize OK / Cancel and Apply buttons
Definition: dialogtool.h:365
bool flagError
flagError use this flag if for you do not enought
Definition: dialogtool.h:193
const VContainer * data
data container with data
Definition: dialogtool.h:177
QPlainTextEdit * plainTextEditFormula
plainTextEditFormula formula
Definition: dialogtool.h:208
bool prepare
prepare show if we prepare. Show dialog after finish working with visual part of tool
Definition: dialogtool.h:228
QLabel * labelResultCalculation
labelResultCalculation label with result of calculation
Definition: dialogtool.h:211
QPointer< Visualization > vis
Definition: dialogtool.h:236
void ChangeColor(QWidget *widget, const QColor &color)
void DeployFormula(QPlainTextEdit *formula, QPushButton *buttonGrowLength, int formulaBaseHeight)
Definition: dialogtool.cpp:992
quint32 getCurrentObjectId(QComboBox *box) const
getCurrentPointId return current point id stored in combobox
Definition: dialogtool.cpp:959
The EditFormulaDialog class dialog for editing wrong formula.
QString GetFormula() const
void SetFormula(const QString &value)
void setPostfix(const QString &value)
IntersectCircleTangentDialog(const VContainer *data, const quint32 &toolId, QWidget *parent=nullptr)
virtual void closeEvent(QCloseEvent *event) Q_DECL_OVERRIDE
closeEvent handle when dialog cloded
virtual void SaveData() Q_DECL_OVERRIDE
SaveData Put dialog data in local variables.
virtual void ChosenObject(quint32 id, const SceneObject &type) Q_DECL_OVERRIDE
virtual void ShowVisualization() Q_DECL_OVERRIDE
Ui::IntersectCircleTangentDialog * ui
virtual void CheckState() Q_DECL_FINAL
CheckState enable, when all is correct, or disable, when something wrong, button ok.
void setCirclesCrossPoint(const CrossCirclesPoint &p)
virtual void RefreshGeometry() Q_DECL_OVERRIDE
void setCrossPoint(const CrossCirclesPoint &value)
The VContainer class container of all variables.
Definition: vcontainer.h:141
virtual void VisualMode(const quint32 &pointId)
void setObject1Id(const quint32 &value)
QString UnitsToStr(const Unit &unit, const bool translate)
UnitsToStr translate unit to string.
Definition: def.cpp:702
#define SCASSERT(cond)
Definition: def.h:317
SceneObject
Definition: def.h:103
CrossCirclesPoint
#define qApp
Definition: vapplication.h:67