Seamly2D
Code documentation
dialogsplinepath.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  * *
3  * Copyright (C) 2017 Seamly, LLC *
4  * *
5  * https://github.com/fashionfreedom/seamly2d *
6  * *
7  ***************************************************************************
8  **
9  ** Seamly2D is free software: you can redistribute it and/or modify
10  ** it under the terms of the GNU General Public License as published by
11  ** the Free Software Foundation, either version 3 of the License, or
12  ** (at your option) any later version.
13  **
14  ** Seamly2D is distributed in the hope that it will be useful,
15  ** but WITHOUT ANY WARRANTY; without even the implied warranty of
16  ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  ** GNU General Public License for more details.
18  **
19  ** You should have received a copy of the GNU General Public License
20  ** along with Seamly2D. If not, see <http://www.gnu.org/licenses/>.
21  **
22  **************************************************************************
23 
24  ************************************************************************
25  **
26  ** @file dialogsplinepath.cpp
27  ** @author Roman Telezhynskyi <dismine(at)gmail.com>
28  ** @date November 15, 2013
29  **
30  ** @brief
31  ** @copyright
32  ** This source code is part of the Valentine project, a pattern making
33  ** program, whose allow create and modeling patterns of clothing.
34  ** Copyright (C) 2013-2015 Seamly2D project
35  ** <https://github.com/fashionfreedom/seamly2d> All Rights Reserved.
36  **
37  ** Seamly2D is free software: you can redistribute it and/or modify
38  ** it under the terms of the GNU General Public License as published by
39  ** the Free Software Foundation, either version 3 of the License, or
40  ** (at your option) any later version.
41  **
42  ** Seamly2D is distributed in the hope that it will be useful,
43  ** but WITHOUT ANY WARRANTY; without even the implied warranty of
44  ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
45  ** GNU General Public License for more details.
46  **
47  ** You should have received a copy of the GNU General Public License
48  ** along with Seamly2D. If not, see <http://www.gnu.org/licenses/>.
49  **
50  *************************************************************************/
51 
52 #include "dialogsplinepath.h"
53 
54 #include <QColor>
55 #include <QComboBox>
56 #include <QDialog>
57 #include <QDialogButtonBox>
58 #include <QFont>
59 #include <QLabel>
60 #include <QLatin1String>
61 #include <QLineEdit>
62 #include <QListWidget>
63 #include <QListWidgetItem>
64 #include <QPlainTextEdit>
65 #include <QPointer>
66 #include <QPushButton>
67 #include <QSharedPointer>
68 #include <QToolButton>
69 #include <QVariant>
70 #include <Qt>
71 #include <new>
72 
73 #include "../../tools/vabstracttool.h"
74 #include "../../visualization/visualization.h"
75 #include "../../visualization/path/vistoolsplinepath.h"
76 #include "../ifc/xml/vdomdocument.h"
77 #include "../qmuparser/qmuparsererror.h"
78 #include "../support/edit_formula_dialog.h"
79 #include "../vgeometry/../ifc/ifcdef.h"
80 #include "../vgeometry/vpointf.h"
81 #include "../vgeometry/vsplinepoint.h"
82 #include "../vmisc/vabstractapplication.h"
83 #include "../vmisc/vcommonsettings.h"
84 #include "../vpatterndb/vcontainer.h"
85 #include "../vwidgets/vabstractmainwindow.h"
86 #include "../vwidgets/vmaingraphicsscene.h"
87 #include "ui_dialogsplinepath.h"
88 #include "vtranslatevars.h"
89 
90 //---------------------------------------------------------------------------------------------------------------------
91 /**
92  * @brief DialogSplinePath create dialog
93  * @param data container with data
94  * @param parent parent widget
95  */
96 DialogSplinePath::DialogSplinePath(const VContainer *data, const quint32 &toolId, QWidget *parent)
97  : DialogTool(data, toolId, parent)
98  , ui(new Ui::DialogSplinePath)
99  , path()
100  , newDuplicate(-1)
101  , formulaBaseHeightAngle1(0)
102  , formulaBaseHeightAngle2(0)
103  , formulaBaseHeightLength1(0)
104  , formulaBaseHeightLength2(0)
105  , flagAngle1()
106  , flagAngle2()
107  , flagLength1()
108  , flagLength2()
109 {
110  ui->setupUi(this);
111  setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
112  setWindowIcon(QIcon(":/toolicon/32x32/splinePath.png"));
113 
114  plainTextEditFormula = ui->plainTextEditAngle1F;
115 
116  formulaBaseHeightAngle1 = ui->plainTextEditAngle1F->height();
117  formulaBaseHeightAngle2 = ui->plainTextEditAngle2F->height();
118  formulaBaseHeightLength1 = ui->plainTextEditLength1F->height();
119  formulaBaseHeightLength2 = ui->plainTextEditLength2F->height();
120 
121  ui->plainTextEditAngle1F->installEventFilter(this);
122  ui->plainTextEditAngle2F->installEventFilter(this);
123  ui->plainTextEditLength1F->installEventFilter(this);
124  ui->plainTextEditLength2F->installEventFilter(this);
125 
127  ok_Button->setEnabled(false);
128 
129  FillComboBoxPoints(ui->comboBoxPoint);
130 
131  int index = ui->lineType_ComboBox->findData(LineTypeNone);
132  if (index != -1)
133  {
134  ui->lineType_ComboBox->removeItem(index);
135  }
136 
137  index = ui->lineColor_ComboBox->findData(qApp->getCurrentDocument()->getDefaultLineColor());
138  if (index != -1)
139  {
140  ui->lineColor_ComboBox->setCurrentIndex(index);
141  }
142 
143  index = ui->lineWeight_ComboBox->findData(qApp->getCurrentDocument()->getDefaultLineWeight());
144  if (index != -1)
145  {
146  ui->lineWeight_ComboBox->setCurrentIndex(index);
147  }
148 
149  index = ui->lineType_ComboBox->findData(qApp->getCurrentDocument()->getDefaultLineType());
150  if (index != -1)
151  {
152  ui->lineType_ComboBox->setCurrentIndex(index);
153  }
154 
155  connect(ui->listWidget, &QListWidget::currentRowChanged, this, &DialogSplinePath::PointChanged);
156  connect(ui->comboBoxPoint, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
158 
159  connect(ui->toolButtonExprAngle1, &QPushButton::clicked, this, &DialogSplinePath::FXAngle1);
160  connect(ui->toolButtonExprAngle2, &QPushButton::clicked, this, &DialogSplinePath::FXAngle2);
161  connect(ui->toolButtonExprLength1, &QPushButton::clicked, this, &DialogSplinePath::FXLength1);
162  connect(ui->toolButtonExprLength2, &QPushButton::clicked, this, &DialogSplinePath::FXLength2);
163 
164  connect(ui->plainTextEditAngle1F, &QPlainTextEdit::textChanged, this, &DialogSplinePath::Angle1Changed);
165  connect(ui->plainTextEditAngle2F, &QPlainTextEdit::textChanged, this, &DialogSplinePath::Angle2Changed);
166  connect(ui->plainTextEditLength1F, &QPlainTextEdit::textChanged, this, &DialogSplinePath::Length1Changed);
167  connect(ui->plainTextEditLength2F, &QPlainTextEdit::textChanged, this, &DialogSplinePath::Length2Changed);
168 
169  connect(ui->pushButtonGrowAngle1, &QPushButton::clicked, this, &DialogSplinePath::DeployAngle1TextEdit);
170  connect(ui->pushButtonGrowAngle2, &QPushButton::clicked, this, &DialogSplinePath::DeployAngle2TextEdit);
171  connect(ui->pushButtonGrowLength1, &QPushButton::clicked, this, &DialogSplinePath::DeployLength1TextEdit);
172  connect(ui->pushButtonGrowLength2, &QPushButton::clicked, this, &DialogSplinePath::DeployLength2TextEdit);
173 
174  vis = new VisToolSplinePath(data);
175  auto path = qobject_cast<VisToolSplinePath *>(vis);
176  SCASSERT(path != nullptr)
177 
178  auto scene = qobject_cast<VMainGraphicsScene *>(qApp->getCurrentScene());
179  SCASSERT(scene != nullptr)
182 }
183 
184 //---------------------------------------------------------------------------------------------------------------------
186 {
187  delete ui;
188 }
189 
190 //---------------------------------------------------------------------------------------------------------------------
191 /**
192  * @brief SetPath set spline path
193  * @param value path
194  */
196 {
197  flagAngle1.clear();
198  flagAngle2.clear();
199  flagLength1.clear();
200  flagLength2.clear();
201 
202  this->path = value;
203  ui->listWidget->blockSignals(true);
204  ui->listWidget->clear();
205  for (qint32 i = 0; i < path.CountPoints(); ++i)
206  {
207  NewItem(path.at(i));
208  }
209  ui->listWidget->setFocus(Qt::OtherFocusReason);
210  ui->lineEditSplPathName->setText(qApp->TrVars()->VarToUser(path.name()));
211 
212  auto visPath = qobject_cast<VisToolSplinePath *>(vis);
213  SCASSERT(visPath != nullptr)
214  visPath->setPath(path);
215  ui->listWidget->blockSignals(false);
216 }
217 
218 //---------------------------------------------------------------------------------------------------------------------
220 {
221  return GetComboBoxCurrentData(ui->lineType_ComboBox, LineTypeSolidLine);
222 }
223 
224 //---------------------------------------------------------------------------------------------------------------------
225 void DialogSplinePath::setPenStyle(const QString &value)
226 {
227  ChangeCurrentData(ui->lineType_ComboBox, value);
228 }
229 
230 //---------------------------------------------------------------------------------------------------------------------
231 /**
232  * @brief getLineWeight return weight of the lines
233  * @return type
234  */
236 {
237  return GetComboBoxCurrentData(ui->lineWeight_ComboBox, "0.35");
238 }
239 
240 //---------------------------------------------------------------------------------------------------------------------
241 /**
242  * @brief setLineWeight set weight of the lines
243  * @param value type
244  */
245 void DialogSplinePath::setLineWeight(const QString &value)
246 {
247  ChangeCurrentData(ui->lineWeight_ComboBox, value);
248 }
249 
250 //---------------------------------------------------------------------------------------------------------------------
252 {
253  return GetComboBoxCurrentData(ui->lineColor_ComboBox, ColorBlack);
254 }
255 
256 //---------------------------------------------------------------------------------------------------------------------
257 void DialogSplinePath::setLineColor(const QString &value)
258 {
259  ChangeCurrentData(ui->lineColor_ComboBox, value);
260 }
261 
262 //---------------------------------------------------------------------------------------------------------------------
263 /**
264  * @brief ChoosedObject gets id and type of selected object. Save right data and ignore wrong.
265  * @param id id of point or detail
266  * @param type don't show this id in list
267  */
268 void DialogSplinePath::ChosenObject(quint32 id, const SceneObject &type)
269 {
270  if (type == SceneObject::Point)
271  {
272  if (AllIds().contains(id))
273  {
274  return;
275  }
276 
277  const auto point = data->GeometricObject<VPointF>(id);
278  VSplinePoint p;
279  p.SetP(*point);
280  NewItem(p);
281  emit ToolTip(tr("Select point of curve path"));
282 
283  SavePath();
284 
285  auto visPath = qobject_cast<VisToolSplinePath *>(vis);
286  SCASSERT(visPath != nullptr)
287  visPath->setPath(path);
288 
289  if (path.CountPoints() == 1)
290  {
291  visPath->VisualMode(NULL_ID);
292  VAbstractMainWindow *window = qobject_cast<VAbstractMainWindow *>(qApp->getMainWindow());
293  SCASSERT(window != nullptr)
295 
297  }
298  else
299  {
300  visPath->RefreshGeometry();
301  }
302  }
303 }
304 
305 //---------------------------------------------------------------------------------------------------------------------
306 /**
307  * @brief SaveData Put dialog data in local variables
308  */
310 {
311  const quint32 d = path.GetDuplicate();//Save previous value
312  SavePath();
313  newDuplicate <= -1 ? path.SetDuplicate(d) : path.SetDuplicate(static_cast<quint32>(newDuplicate));
314 
315  auto visPath = qobject_cast<VisToolSplinePath *>(vis);
316  SCASSERT(visPath != nullptr)
317  visPath->setPath(path);
318  visPath->SetMode(Mode::Show);
319  visPath->RefreshGeometry();
320 }
321 
322 //---------------------------------------------------------------------------------------------------------------------
324 {
325  SCASSERT(ok_Button != nullptr)
326 
327  bool fAngle1 = true, fAngle2 = true, fLength1 = true, fLength2 = true;
328 
329  for (qint32 i = 0; i < ui->listWidget->count(); ++i)
330  {
331  fAngle1 = fAngle1 && flagAngle1.at(i);
332  fAngle2 = fAngle2 && flagAngle2.at(i);
333  fLength1 = fLength1 && flagLength1.at(i);
334  fLength2 = fLength2 && flagLength2.at(i);
335  }
336 
337  ok_Button->setEnabled(fAngle1 && fAngle2 && fLength1 && fLength2 && flagError);
338  // In case dialog hasn't apply button
339  if (apply_Button != nullptr)
340  {
341  apply_Button->setEnabled(ok_Button->isEnabled());
342  }
343 }
344 
345 //---------------------------------------------------------------------------------------------------------------------
346 void DialogSplinePath::closeEvent(QCloseEvent *event)
347 {
348  ui->plainTextEditAngle1F->blockSignals(true);
349  ui->plainTextEditAngle2F->blockSignals(true);
350  ui->plainTextEditLength1F->blockSignals(true);
351  ui->plainTextEditLength2F->blockSignals(true);
352  DialogTool::closeEvent(event);
353 }
354 
355 //---------------------------------------------------------------------------------------------------------------------
357 {
358  DeployFormula(ui->plainTextEditAngle1F, ui->pushButtonGrowAngle1, formulaBaseHeightAngle1);
359  collapseFormula(ui->plainTextEditAngle2F, ui->pushButtonGrowAngle2, formulaBaseHeightAngle2);
360  collapseFormula(ui->plainTextEditLength1F, ui->pushButtonGrowLength1, formulaBaseHeightLength1);
361  collapseFormula(ui->plainTextEditLength2F, ui->pushButtonGrowLength2, formulaBaseHeightLength2);
362 }
363 
364 //---------------------------------------------------------------------------------------------------------------------
366 {
367  DeployFormula(ui->plainTextEditAngle2F, ui->pushButtonGrowAngle2, formulaBaseHeightAngle2);
368  collapseFormula(ui->plainTextEditAngle1F, ui->pushButtonGrowAngle1, formulaBaseHeightAngle1);
369  collapseFormula(ui->plainTextEditLength1F, ui->pushButtonGrowLength1, formulaBaseHeightLength1);
370  collapseFormula(ui->plainTextEditLength2F, ui->pushButtonGrowLength2, formulaBaseHeightLength2);
371 }
372 
373 //---------------------------------------------------------------------------------------------------------------------
375 {
376  DeployFormula(ui->plainTextEditLength1F, ui->pushButtonGrowLength1, formulaBaseHeightLength1);
377  collapseFormula(ui->plainTextEditAngle1F, ui->pushButtonGrowAngle1, formulaBaseHeightAngle1);
378  collapseFormula(ui->plainTextEditAngle2F, ui->pushButtonGrowAngle2, formulaBaseHeightAngle2);
379  collapseFormula(ui->plainTextEditLength2F, ui->pushButtonGrowLength2, formulaBaseHeightLength2);
380 }
381 
382 //---------------------------------------------------------------------------------------------------------------------
384 {
385  DeployFormula(ui->plainTextEditLength2F, ui->pushButtonGrowLength2, formulaBaseHeightLength2);
386  collapseFormula(ui->plainTextEditAngle1F, ui->pushButtonGrowAngle1, formulaBaseHeightAngle1);
387  collapseFormula(ui->plainTextEditAngle2F, ui->pushButtonGrowAngle2, formulaBaseHeightAngle2);
388  collapseFormula(ui->plainTextEditLength1F, ui->pushButtonGrowLength1, formulaBaseHeightLength1);
389 }
390 
391 //---------------------------------------------------------------------------------------------------------------------
393 {
394  const int row = ui->listWidget->currentRow();
395  if (row == -1)
396  {
397  return;
398  }
399 
400  if (row != 0)
401  {
402  QListWidgetItem *item = ui->listWidget->item(row);
403  SCASSERT(item != nullptr)
404  VSplinePoint p = qvariant_cast<VSplinePoint>(item->data(Qt::UserRole));
405 
406  const QString angle1F = ui->plainTextEditAngle1F->toPlainText().replace("\n", " ");
407  const qreal angle1 = Visualization::FindVal(angle1F, data->DataVariables());
408 
409  try
410  {
411  p.SetAngle1(angle1, qApp->TrVars()->FormulaFromUser(angle1F, qApp->Settings()->GetOsSeparator()));
412  }
413  catch (qmu::QmuParserError &e)
414  {
415  Q_UNUSED(e)
416  p.SetAngle1(angle1, angle1F);
417  }
418 
419  item->setData(Qt::UserRole, QVariant::fromValue(p));
420 
421  EvalAngle1();
422 
423  if (row != ui->listWidget->count()-1)
424  {
425  ui->plainTextEditAngle2F->blockSignals(true);
426  ui->plainTextEditAngle2F->setPlainText(qApp->TrVars()->FormulaToUser(p.Angle2Formula(),
427  qApp->Settings()->GetOsSeparator()));
428  EvalAngle2();
429  ui->plainTextEditAngle2F->blockSignals(false);
430  }
431  }
432 }
433 
434 //---------------------------------------------------------------------------------------------------------------------
436 {
437  const int row = ui->listWidget->currentRow();
438  if (row == -1)
439  {
440  return;
441  }
442 
443  if (row != ui->listWidget->count()-1)
444  {
445  QListWidgetItem *item = ui->listWidget->item(row);
446  SCASSERT(item != nullptr)
447  VSplinePoint p = qvariant_cast<VSplinePoint>(item->data(Qt::UserRole));
448 
449  const QString angle2F = ui->plainTextEditAngle2F->toPlainText().replace("\n", " ");
450  const qreal angle2 = Visualization::FindVal(angle2F, data->DataVariables());
451 
452  try
453  {
454  p.SetAngle2(angle2, qApp->TrVars()->FormulaFromUser(angle2F, qApp->Settings()->GetOsSeparator()));
455  }
456  catch (qmu::QmuParserError &e)
457  {
458  Q_UNUSED(e)
459  p.SetAngle2(angle2, angle2F);
460  }
461 
462  item->setData(Qt::UserRole, QVariant::fromValue(p));
463 
464  EvalAngle2();
465 
466  if (row != 0)
467  {
468  ui->plainTextEditAngle1F->blockSignals(true);
469  ui->plainTextEditAngle1F->setPlainText(qApp->TrVars()->FormulaToUser(p.Angle1Formula(),
470  qApp->Settings()->GetOsSeparator()));
471  EvalAngle1();
472  ui->plainTextEditAngle1F->blockSignals(false);
473  }
474  }
475 }
476 
477 //---------------------------------------------------------------------------------------------------------------------
479 {
480  const int row = ui->listWidget->currentRow();
481  if (row == -1)
482  {
483  return;
484  }
485 
486  if (row != 0)
487  {
488  QListWidgetItem *item = ui->listWidget->item(row);
489  SCASSERT(item != nullptr)
490  VSplinePoint p = qvariant_cast<VSplinePoint>(item->data(Qt::UserRole));
491 
492  const QString length1F = ui->plainTextEditLength1F->toPlainText().replace("\n", " ");
493  const qreal length1 = Visualization::FindLength(length1F, data->DataVariables());
494 
495  try
496  {
497  p.SetLength1(length1, qApp->TrVars()->FormulaFromUser(length1F, qApp->Settings()->GetOsSeparator()));
498  }
499  catch (qmu::QmuParserError &e)
500  {
501  Q_UNUSED(e)
502  p.SetLength1(length1, length1F);
503  }
504 
505  item->setData(Qt::UserRole, QVariant::fromValue(p));
506 
507  EvalLength1();
508  }
509 }
510 
511 //---------------------------------------------------------------------------------------------------------------------
513 {
514  const int row = ui->listWidget->currentRow();
515  if (row == -1)
516  {
517  return;
518  }
519 
520  if (row != ui->listWidget->count()-1)
521  {
522  QListWidgetItem *item = ui->listWidget->item(row);
523  SCASSERT(item != nullptr)
524  VSplinePoint p = qvariant_cast<VSplinePoint>(item->data(Qt::UserRole));
525 
526  const QString length2F = ui->plainTextEditLength2F->toPlainText().replace("\n", " ");
527  const qreal length2 = Visualization::FindLength(length2F, data->DataVariables());
528 
529  try
530  {
531  p.SetLength2(length2, qApp->TrVars()->FormulaFromUser(length2F, qApp->Settings()->GetOsSeparator()));
532  }
533  catch (qmu::QmuParserError &e)
534  {
535  Q_UNUSED(e)
536  p.SetLength2(length2, length2F);
537  }
538 
539  item->setData(Qt::UserRole, QVariant::fromValue(p));
540 
541  EvalLength2();
542  }
543 }
544 
545 //---------------------------------------------------------------------------------------------------------------------
547 {
548  auto dialog = new EditFormulaDialog(data, toolId, this);
549  dialog->setWindowTitle(tr("Edit first control point angle"));
550 
551  QString angle1F = qApp->TrVars()->TryFormulaFromUser(ui->plainTextEditAngle1F->toPlainText().replace("\n", " "),
552  qApp->Settings()->GetOsSeparator());
553 
554  dialog->SetFormula(angle1F);
555  dialog->setPostfix(degreeSymbol);
556  if (dialog->exec() == QDialog::Accepted)
557  {
558  angle1F = qApp->TrVars()->FormulaToUser(dialog->GetFormula(), qApp->Settings()->GetOsSeparator());
559  // increase height if needed.
560  if (angle1F.length() > 80)
561  {
563  }
564  ui->plainTextEditAngle1F->setPlainText(angle1F);
565  MoveCursorToEnd(ui->plainTextEditAngle1F);
566  }
567  delete dialog;
568 }
569 
570 //---------------------------------------------------------------------------------------------------------------------
572 {
573  auto dialog = new EditFormulaDialog(data, toolId, this);
574  dialog->setWindowTitle(tr("Edit second control point angle"));
575 
576  QString angle2F = qApp->TrVars()->TryFormulaFromUser(ui->plainTextEditAngle2F->toPlainText().replace("\n", " "),
577  qApp->Settings()->GetOsSeparator());
578 
579  dialog->SetFormula(angle2F);
580  dialog->setPostfix(degreeSymbol);
581  if (dialog->exec() == QDialog::Accepted)
582  {
583  angle2F = qApp->TrVars()->FormulaToUser(dialog->GetFormula(), qApp->Settings()->GetOsSeparator());
584  // increase height if needed.
585  if (angle2F.length() > 80)
586  {
588  }
589  ui->plainTextEditAngle2F->setPlainText(angle2F);
590  MoveCursorToEnd(ui->plainTextEditAngle2F);
591  }
592  delete dialog;
593 }
594 
595 //---------------------------------------------------------------------------------------------------------------------
597 {
598  auto dialog = new EditFormulaDialog(data, toolId, this);
599  dialog->setWindowTitle(tr("Edit first control point length"));
600 
601  QString length1F = qApp->TrVars()->TryFormulaFromUser(ui->plainTextEditLength1F->toPlainText().replace("\n", " "),
602  qApp->Settings()->GetOsSeparator());
603 
604  dialog->SetFormula(length1F);
605  dialog->setPostfix(UnitsToStr(qApp->patternUnit(), true));
606  if (dialog->exec() == QDialog::Accepted)
607  {
608  length1F = qApp->TrVars()->FormulaToUser(dialog->GetFormula(), qApp->Settings()->GetOsSeparator());
609  // increase height if needed.
610  if (length1F.length() > 80)
611  {
613  }
614  ui->plainTextEditLength1F->setPlainText(length1F);
615  MoveCursorToEnd(ui->plainTextEditLength1F);
616  }
617  delete dialog;
618 }
619 
620 //---------------------------------------------------------------------------------------------------------------------
622 {
623  auto dialog = new EditFormulaDialog(data, toolId, this);
624  dialog->setWindowTitle(tr("Edit second control point length"));
625 
626  QString length2F = qApp->TrVars()->TryFormulaFromUser(ui->plainTextEditLength2F->toPlainText().replace("\n", " "),
627  qApp->Settings()->GetOsSeparator());
628 
629  dialog->SetFormula(length2F);
630  dialog->setPostfix(UnitsToStr(qApp->patternUnit(), true));
631  if (dialog->exec() == QDialog::Accepted)
632  {
633  length2F = qApp->TrVars()->FormulaToUser(dialog->GetFormula(), qApp->Settings()->GetOsSeparator());
634  // increase height if needed.
635  if (length2F.length() > 80)
636  {
638  }
639  ui->plainTextEditLength2F->setPlainText(length2F);
640  MoveCursorToEnd(ui->plainTextEditLength2F);
641  }
642  delete dialog;
643 }
644 
645 //---------------------------------------------------------------------------------------------------------------------
647 {
648  const int row = ui->listWidget->currentRow();
649  if (row == -1)
650  {
651  return;
652  }
653 
654  labelEditFormula = ui->labelEditAngle1;
655  Eval(ui->plainTextEditAngle1F->toPlainText(), flagAngle1[row], ui->labelResultAngle1, degreeSymbol, false);
656 
657  QListWidgetItem *item = ui->listWidget->item(row);
658  SCASSERT(item != nullptr)
659  VSplinePoint p = qvariant_cast<VSplinePoint>(item->data(Qt::UserRole));
660 
661  ShowPointIssue(p.P().name());
662 }
663 
664 //---------------------------------------------------------------------------------------------------------------------
666 {
667  const int row = ui->listWidget->currentRow();
668  if (row == -1)
669  {
670  return;
671  }
672 
673  labelEditFormula = ui->labelEditAngle2;
674  Eval(ui->plainTextEditAngle2F->toPlainText(), flagAngle2[row], ui->labelResultAngle2, degreeSymbol, false);
675 
676  QListWidgetItem *item = ui->listWidget->item(row);
677  SCASSERT(item != nullptr)
678  VSplinePoint p = qvariant_cast<VSplinePoint>(item->data(Qt::UserRole));
679 
680  ShowPointIssue(p.P().name());
681 }
682 
683 //---------------------------------------------------------------------------------------------------------------------
685 {
686  const int row = ui->listWidget->currentRow();
687  if (row == -1)
688  {
689  return;
690  }
691 
692  labelEditFormula = ui->labelEditLength1;
693  const QString postfix = UnitsToStr(qApp->patternUnit(), true);
694  const qreal length1 = Eval(ui->plainTextEditLength1F->toPlainText(), flagLength1[row], ui->labelResultLength1,
695  postfix, false);
696 
697  if (length1 < 0)
698  {
699  flagLength1[row] = false;
700  ChangeColor(labelEditFormula, Qt::red);
701  ui->labelResultLength1->setText(tr("Error") + QLatin1String(" (") + postfix + QLatin1String(")"));
702  ui->labelResultLength1->setToolTip(tr("Length can't be negative"));
703 
704  CheckState();
705  }
706 
707  QListWidgetItem *item = ui->listWidget->item(row);
708  SCASSERT(item != nullptr)
709  VSplinePoint p = qvariant_cast<VSplinePoint>(item->data(Qt::UserRole));
710 
711  ShowPointIssue(p.P().name());
712 }
713 
714 //---------------------------------------------------------------------------------------------------------------------
716 {
717  const int row = ui->listWidget->currentRow();
718  if (row == -1)
719  {
720  return;
721  }
722 
723  labelEditFormula = ui->labelEditLength2;
724  const QString postfix = UnitsToStr(qApp->patternUnit(), true);
725  const qreal length2 = Eval(ui->plainTextEditLength2F->toPlainText(), flagLength2[row], ui->labelResultLength2,
726  postfix, false);
727 
728  if (length2 < 0)
729  {
730  flagLength2[row] = false;
731  ChangeColor(labelEditFormula, Qt::red);
732  ui->labelResultLength2->setText(tr("Error") + QLatin1String(" (") + postfix + QLatin1String(")"));
733  ui->labelResultLength2->setToolTip(tr("Length can't be negative"));
734 
735  CheckState();
736  }
737 
738  QListWidgetItem *item = ui->listWidget->item(row);
739  SCASSERT(item != nullptr)
740  VSplinePoint p = qvariant_cast<VSplinePoint>(item->data(Qt::UserRole));
741 
742  ShowPointIssue(p.P().name());
743 }
744 
745 //---------------------------------------------------------------------------------------------------------------------
746 /**
747  * @brief PointChanged selected another point in list
748  * @param row number of row
749  */
751 {
752  if (ui->listWidget->count() == 0)
753  {
754  return;
755  }
756 
757  const auto p = qvariant_cast<VSplinePoint>(ui->listWidget->item(row)->data(Qt::UserRole));
758  DataPoint(p);
759 }
760 
761 //---------------------------------------------------------------------------------------------------------------------
762 /**
763  * @brief currentPointChanged changed point in combo box
764  * @param index index in list
765  */
767 {
768  const quint32 id = qvariant_cast<quint32>(ui->comboBoxPoint->itemData(index));
769  QListWidgetItem *item = ui->listWidget->item( ui->listWidget->currentRow() );
770  VSplinePoint p = qvariant_cast<VSplinePoint>(item->data(Qt::UserRole));
771  const auto point = data->GeometricObject<VPointF>(id);
772  p.SetP(*point);
773  DataPoint(p);
774  item->setData(Qt::UserRole, QVariant::fromValue(p));
775  ShowPointIssue(p.P().name());
776 
777  QColor color = okColor;
778  if (not IsPathValid())
779  {
780  flagError = false;
781  color = errorColor;
782 
783  ui->lineEditSplPathName->setText(tr("Invalid spline path"));
784  }
785  else
786  {
787  flagError = true;
788  color = okColor;
789 
790  auto first = qvariant_cast<VSplinePoint>(ui->listWidget->item(0)->data(Qt::UserRole));
791  auto last = qvariant_cast<VSplinePoint>(ui->listWidget->item(ui->listWidget->count()-1)->data(Qt::UserRole));
792 
793  if (first.P().id() == path.at(0).P().id() && last.P().id() == path.at(path.CountPoints()-1).P().id())
794  {
795  newDuplicate = -1;
796  ui->lineEditSplPathName->setText(qApp->TrVars()->VarToUser(path.name()));
797  }
798  else
799  {
800  VSplinePath newPath = ExtractPath();
801 
802  if (not data->IsUnique(newPath.name()))
803  {
804  newDuplicate = static_cast<qint32>(DNumber(newPath.name()));
805  newPath.SetDuplicate(static_cast<quint32>(newDuplicate));
806  }
807 
808  ui->lineEditSplPathName->setText(qApp->TrVars()->VarToUser(newPath.name()));
809  }
810  }
811  ChangeColor(ui->labelName, color);
812  ChangeColor(ui->labelPoint, color);
813  CheckState();
814 }
815 
816 //---------------------------------------------------------------------------------------------------------------------
818 {
819  if (click == false)
820  {
821  if (path.CountPoints() >= 3)
822  {
823  emit ToolTip("");
824 
825  if (not data->IsUnique(path.name()))
826  {
828  }
829 
830  DialogAccepted();
831  }
832  }
833 }
834 
835 //---------------------------------------------------------------------------------------------------------------------
837 {
838  SetPath(path);
839 }
840 
841 //---------------------------------------------------------------------------------------------------------------------
843 {
844  AddVisualization<VisToolSplinePath>();
845 }
846 
847 //---------------------------------------------------------------------------------------------------------------------
848 /**
849  * @brief NewItem add point to list
850  * @param point spline path point
851  */
853 {
854  flagAngle1.append(true);
855  flagLength1.append(true);
856  flagAngle2.append(true);
857  flagLength2.append(true);
858 
859  auto item = new QListWidgetItem(point.P().name());
860  item->setData(Qt::UserRole, QVariant::fromValue(point));
861 
862  ui->listWidget->addItem(item);
863  ui->listWidget->setCurrentItem(item);
864  if (ui->listWidget->count() >= 2)
865  {
866  ok_Button = ui->buttonBox->button(QDialogButtonBox::Ok);
867  ok_Button->setEnabled(true);
868  }
869 
870  DataPoint(point);
871 }
872 
873 //---------------------------------------------------------------------------------------------------------------------
874 /**
875  * @brief dataPoint show data of point in fields
876  * @param p spline path point
877  */
879 {
880  ui->comboBoxPoint->blockSignals(true);
881  ChangeCurrentData(ui->comboBoxPoint, p.P().id());
882  ui->comboBoxPoint->blockSignals(false);
883 
884  int row = ui->listWidget->currentRow();
885  const QString notUsed = tr("Not used");
886  const QString result = tr("Result value");
887  const QString emptyResult = QString("NA");
888 
889  if (row == 0)
890  {
891  ui->toolButtonExprAngle1->setEnabled(false);
892  ui->labelResultAngle1->setText(emptyResult);
893  ui->labelResultAngle1->setToolTip(result);
894  ChangeColor(ui->labelEditAngle1, okColor);
895  ui->plainTextEditAngle1F->blockSignals(true);
896  ui->plainTextEditAngle1F->setPlainText(notUsed);
897  ui->plainTextEditAngle1F->setEnabled(false);
898  ui->pushButtonGrowAngle1->setEnabled(false);
899  ui->plainTextEditAngle1F->blockSignals(false);
900 
901  ui->toolButtonExprLength1->setEnabled(false);
902  ui->labelResultLength1->setText(emptyResult);
903  ui->labelResultLength1->setToolTip(result);
904  ChangeColor(ui->labelEditLength1, okColor);
905  ui->plainTextEditLength1F->blockSignals(true);
906  ui->plainTextEditLength1F->setPlainText(notUsed);
907  ui->plainTextEditLength1F->setEnabled(false);
908  ui->pushButtonGrowLength1->setEnabled(false);
909  ui->plainTextEditLength1F->blockSignals(false);
910 
911  ui->plainTextEditAngle2F->setEnabled(true);
912  ui->plainTextEditLength2F->setEnabled(true);
913 
914  ui->toolButtonExprAngle2->setEnabled(true);
915  ui->toolButtonExprLength2->setEnabled(true);
916 
917  ui->plainTextEditAngle2F->blockSignals(true);
918  ui->plainTextEditLength2F->blockSignals(true);
919  ui->plainTextEditAngle2F->setPlainText(qApp->TrVars()->FormulaToUser(p.Angle2Formula(),
920  qApp->Settings()->GetOsSeparator()));
921  EvalAngle2();
922  ui->plainTextEditLength2F->setPlainText(qApp->TrVars()->FormulaToUser(p.Length2Formula(),
923  qApp->Settings()->GetOsSeparator()));
924  EvalLength2();
925  ui->plainTextEditAngle2F->blockSignals(false);
926  ui->plainTextEditLength2F->blockSignals(false);
927  }
928  else if (row == ui->listWidget->count()-1)
929  {
930  ui->toolButtonExprAngle2->setEnabled(false);
931  ui->labelResultAngle2->setText(emptyResult);
932  ui->labelResultAngle2->setToolTip(result);
933  ChangeColor(ui->labelEditAngle2, okColor);
934  ui->plainTextEditAngle2F->blockSignals(true);
935  ui->plainTextEditAngle2F->setPlainText(notUsed);
936  ui->plainTextEditAngle2F->setEnabled(false);
937  ui->pushButtonGrowAngle2->setEnabled(false);
938  ui->plainTextEditAngle2F->blockSignals(false);
939 
940  ui->toolButtonExprLength2->setEnabled(false);
941  ui->labelResultLength2->setText(emptyResult);
942  ui->labelResultLength2->setToolTip(result);
943  ChangeColor(ui->labelEditLength2, okColor);
944  ui->plainTextEditLength2F->blockSignals(true);
945  ui->plainTextEditLength2F->setPlainText(notUsed);
946  ui->plainTextEditLength2F->setEnabled(false);
947  ui->pushButtonGrowLength2->setEnabled(false);
948  ui->plainTextEditLength2F->blockSignals(false);
949 
950  ui->plainTextEditAngle1F->setEnabled(true);
951  ui->plainTextEditLength1F->setEnabled(true);
952 
953  ui->toolButtonExprAngle1->setEnabled(true);
954  ui->toolButtonExprLength1->setEnabled(true);
955 
956  ui->plainTextEditAngle1F->blockSignals(true);
957  ui->plainTextEditLength1F->blockSignals(true);
958  ui->plainTextEditAngle1F->setPlainText(qApp->TrVars()->FormulaToUser(p.Angle1Formula(),
959  qApp->Settings()->GetOsSeparator()));
960  EvalAngle1();
961  ui->plainTextEditLength1F->setPlainText(qApp->TrVars()->FormulaToUser(p.Length1Formula(),
962  qApp->Settings()->GetOsSeparator()));
963  EvalLength1();
964  ui->plainTextEditAngle1F->blockSignals(false);
965  ui->plainTextEditLength1F->blockSignals(false);
966  }
967  else
968  {
969  ui->pushButtonGrowAngle1->setEnabled(true);
970  ui->pushButtonGrowAngle2->setEnabled(true);
971  ui->pushButtonGrowLength1->setEnabled(true);
972  ui->pushButtonGrowLength2->setEnabled(true);
973 
974  ui->toolButtonExprAngle1->setEnabled(true);
975  ui->toolButtonExprLength1->setEnabled(true);
976  ui->toolButtonExprAngle2->setEnabled(true);
977  ui->toolButtonExprLength2->setEnabled(true);
978 
979  ui->plainTextEditAngle1F->setEnabled(true);
980  ui->plainTextEditLength1F->setEnabled(true);
981  ui->plainTextEditAngle2F->setEnabled(true);
982  ui->plainTextEditLength2F->setEnabled(true);
983 
984  ui->plainTextEditAngle1F->blockSignals(true);
985  ui->plainTextEditLength1F->blockSignals(true);
986  ui->plainTextEditAngle2F->blockSignals(true);
987  ui->plainTextEditLength2F->blockSignals(true);
988 
989  ui->plainTextEditAngle1F->setPlainText(qApp->TrVars()->FormulaToUser(p.Angle1Formula(),
990  qApp->Settings()->GetOsSeparator()));
991  ui->plainTextEditAngle2F->setPlainText(qApp->TrVars()->FormulaToUser(p.Angle2Formula(),
992  qApp->Settings()->GetOsSeparator()));
993  ui->plainTextEditLength1F->setPlainText(qApp->TrVars()->FormulaToUser(p.Length1Formula(),
994  qApp->Settings()->GetOsSeparator()));
995  ui->plainTextEditLength2F->setPlainText(qApp->TrVars()->FormulaToUser(p.Length2Formula(),
996  qApp->Settings()->GetOsSeparator()));
997 
998  EvalAngle1();
999  EvalLength1();
1000  EvalAngle2();
1001  EvalLength2();
1002 
1003  ui->plainTextEditAngle1F->blockSignals(false);
1004  ui->plainTextEditLength1F->blockSignals(false);
1005  ui->plainTextEditAngle2F->blockSignals(false);
1006  ui->plainTextEditLength2F->blockSignals(false);
1007  }
1008 }
1009 
1010 //---------------------------------------------------------------------------------------------------------------------
1012 {
1013  path.Clear();
1014  path = ExtractPath();
1015 }
1016 
1017 //---------------------------------------------------------------------------------------------------------------------
1018 QSet<quint32> DialogSplinePath::AllIds() const
1019 {
1020  QSet<quint32> ids;
1021  for (qint32 i = 0; i < ui->listWidget->count(); ++i)
1022  {
1023  ids.insert(qvariant_cast<VSplinePoint>(ui->listWidget->item(i)->data(Qt::UserRole)).P().id());
1024  }
1025 
1026  return ids;
1027 }
1028 
1029 //---------------------------------------------------------------------------------------------------------------------
1031 {
1032  if (path.CountPoints() < 3)
1033  {
1034  return false;
1035  }
1036 
1037  return (AllIds().size() == path.CountPoints());
1038 }
1039 
1040 //---------------------------------------------------------------------------------------------------------------------
1042 {
1043  QVector<VSplinePoint> points;
1044  for (qint32 i = 0; i < ui->listWidget->count(); ++i)
1045  {
1046  points.append(qvariant_cast<VSplinePoint>(ui->listWidget->item(i)->data(Qt::UserRole)));
1047  }
1048  return VSplinePath(points);
1049 }
1050 
1051 //---------------------------------------------------------------------------------------------------------------------
1052 void DialogSplinePath::ShowPointIssue(const QString &pName)
1053 {
1054  const int row = ui->listWidget->currentRow();
1055  if (row == -1)
1056  {
1057  return;
1058  }
1059 
1060  QListWidgetItem *item = ui->listWidget->item(row);
1061  SCASSERT(item != nullptr)
1062 
1063  if (flagAngle1.at(row) && flagAngle2.at(row) && flagLength1.at(row) && flagLength2.at(row))
1064  {
1065  item->setText(pName);
1066  }
1067  else
1068  {
1069  item->setText(pName + QLatin1String("(!)"));
1070  }
1071 }
1072 
1073 //---------------------------------------------------------------------------------------------------------------------
1074 void DialogSplinePath::collapseFormula(QPlainTextEdit *textEdit, QPushButton *pushButton, int height)
1075 {
1076  SCASSERT(textEdit != nullptr)
1077  SCASSERT(pushButton != nullptr)
1078 
1079  const QTextCursor cursor = textEdit->textCursor();
1080 
1081  setMaximumWidth(260);
1082  textEdit->setFixedHeight(height);
1083  pushButton->setIcon(QIcon::fromTheme("go-down", QIcon(":/icons/win.icon.theme/16x16/actions/go-down.png")));
1084  setUpdatesEnabled(false);
1085  repaint();
1086  setUpdatesEnabled(true);
1087  textEdit->setFocus();
1088  textEdit->setTextCursor(cursor);
1089 }
The DialogSplinePath class dialog for ToolSplinePath. Help create spline path and edit option.
QVector< bool > flagAngle2
QSet< quint32 > AllIds() const
QVector< bool > flagLength2
QVector< bool > flagAngle1
flagAngle1 true if value of first angle is correct
QString getPenStyle() const
virtual ~DialogSplinePath() Q_DECL_OVERRIDE
QVector< bool > flagLength1
Ui::DialogSplinePath * ui
ui keeps information about user interface
virtual void SaveData() Q_DECL_OVERRIDE
SaveData Put dialog data in local variables.
virtual void CheckState() Q_DECL_FINAL
CheckState enable, when all is correct, or disable, when something wrong, button ok.
void PointChanged(int row)
PointChanged selected another point in list.
void SetPath(const VSplinePath &value)
SetPath set spline path.
bool IsPathValid() const
void NewItem(const VSplinePoint &point)
NewItem add point to list.
virtual void closeEvent(QCloseEvent *event) Q_DECL_OVERRIDE
closeEvent handle when dialog cloded
void collapseFormula(QPlainTextEdit *textEdit, QPushButton *pushButton, int height)
void setPenStyle(const QString &value)
DialogSplinePath(const VContainer *data, const quint32 &toolId, QWidget *parent=nullptr)
DialogSplinePath create dialog.
void setLineColor(const QString &value)
QString getLineColor() const
virtual void ChosenObject(quint32 id, const SceneObject &type) Q_DECL_OVERRIDE
ChoosedObject gets id and type of selected object. Save right data and ignore wrong.
int formulaBaseHeightAngle1
formulaBaseHeight base height defined by dialogui
virtual void ShowDialog(bool click) Q_DECL_OVERRIDE
void setLineWeight(const QString &value)
setLineWeight set weight of the lines
virtual void ShowVisualization() Q_DECL_OVERRIDE
void currentPointChanged(int index)
currentPointChanged changed point in combo box
void PathUpdated(const VSplinePath &path)
void ShowPointIssue(const QString &pName)
QString getLineWeight() const
getLineWeight return weight of the lines
void DataPoint(const VSplinePoint &p)
dataPoint show data of point in fields
VSplinePath path
path spline path
VSplinePath ExtractPath() const
The DialogTool class parent for all dialog of tools.
Definition: dialogtool.h:107
void ChangeCurrentData(QComboBox *box, const QVariant &value) const
ChangeCurrentData select item in combobox by id.
Definition: dialogtool.cpp:419
quint32 DNumber(const QString &baseName) const
Definition: dialogtool.cpp:476
const QColor okColor
Definition: dialogtool.h:219
void ToolTip(const QString &toolTip)
ToolTip emit tooltipe for tool.
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 MoveCursorToEnd(QPlainTextEdit *plainTextEdit) const
Definition: dialogtool.cpp:432
QPushButton * ok_Button
ok_Button button ok
Definition: dialogtool.h:199
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
virtual void closeEvent(QCloseEvent *event) Q_DECL_OVERRIDE
closeEvent handle when dialog cloded
Definition: dialogtool.cpp:192
virtual void DialogAccepted()
DialogAccepted save data and emit signal about closed dialog.
QPushButton * apply_Button
apply_Button button apply
Definition: dialogtool.h:202
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
QString GetComboBoxCurrentData(const QComboBox *box, const QString &def) const
Definition: dialogtool.cpp:400
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
The EditFormulaDialog class dialog for editing wrong formula.
void SetDuplicate(quint32 number)
quint32 GetDuplicate() const
virtual void ShowToolTip(const QString &toolTip)=0
The VContainer class container of all variables.
Definition: vcontainer.h:141
static bool IsUnique(const QString &name)
Definition: vcontainer.cpp:585
const QHash< QString, QSharedPointer< VInternalVariable > > * DataVariables() const
Definition: vcontainer.cpp:718
const QSharedPointer< T > GeometricObject(const quint32 &id) const
Definition: vcontainer.h:266
virtual QString name() const
name return name graphical object.
Definition: vgobject.cpp:148
quint32 id() const
id return id object.
Definition: vgobject.cpp:205
The VPointF class keep data of point.
Definition: vpointf.h:75
The VSplinePath class keep information about splinePath.
Definition: vsplinepath.h:72
const VSplinePoint & at(int indx) const
at return spline point by index.
virtual qint32 CountPoints() const Q_DECL_OVERRIDE
CountPoints return count of points.
virtual void Clear() Q_DECL_OVERRIDE
Clear clear list of points.
The VSplinePoint class keep information about point in spline path. Each point have two angles and tw...
Definition: vsplinepoint.h:108
QString Length1Formula() const
void SetAngle1(const qreal &value, const QString &angle1F)
QString Angle2Formula() const
void SetP(const VPointF &value)
void SetLength1(const qreal &value, const QString &length1F)
QString Length2Formula() const
QString Angle1Formula() const
void SetLength2(const qreal &value, const QString &length2F)
void SetAngle2(const qreal &value, const QString &angle2F)
VPointF P() const
void PathChanged(const VSplinePath &path)
void ToolTip(const QString &toolTip)
static qreal FindLength(const QString &expression, const QHash< QString, QSharedPointer< VInternalVariable > > *vars)
static qreal FindVal(const QString &expression, const QHash< QString, QSharedPointer< VInternalVariable > > *vars)
Error class of the parser.
const QString degreeSymbol
Definition: def.cpp:196
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
const QString LineTypeSolidLine
Definition: ifcdef.cpp:159
const QString ColorBlack
Definition: ifcdef.cpp:373
const QString LineTypeNone
Definition: ifcdef.cpp:158
#define NULL_ID
Definition: ifcdef.h:76
#define qApp
Definition: vapplication.h:67