Seamly2D
Code documentation
pattern_piece_dialog.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  ** @file pattern_piece_dialog.cpp
3  ** @author Douglas S Caskey
4  ** @date Dec 11, 2022
5  **
6  ** @copyright
7  ** Copyright (C) 2017 - 2022 Seamly, LLC
8  ** https://github.com/fashionfreedom/seamly2d
9  **
10  ** @brief
11  ** Seamly2D is free software: you can redistribute it and/or modify
12  ** it under the terms of the GNU General Public License as published by
13  ** the Free Software Foundation, either version 3 of the License, or
14  ** (at your option) any later version.
15  **
16  ** Seamly2D is distributed in the hope that it will be useful,
17  ** but WITHOUT ANY WARRANTY; without even the implied warranty of
18  ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  ** GNU General Public License for more details.
20  **
21  ** You should have received a copy of the GNU General Public License
22  ** along with Seamly2D. if not, see <http://www.gnu.org/licenses/>.
23  **************************************************************************/
24 
25 /************************************************************************
26  **
27  ** @file seamallowance.cpp
28  ** @author Roman Telezhynskyi <dismine(at)gmail.com>
29  ** @date 3 11, 2016
30  **
31  ** @brief
32  ** @copyright
33  ** This source code is part of the Valentina project, a pattern making
34  ** program, whose allow create and modeling patterns of clothing.
35  ** Copyright (C) 2016 Valentina project
36  ** <https://bitbucket.org/dismine/valentina> All Rights Reserved.
37  **
38  ** Valentina is free software: you can redistribute it and/or modify
39  ** it under the terms of the GNU General Public License as published by
40  ** the Free Software Foundation, either version 3 of the License, or
41  ** (at your option) any later version.
42  **
43  ** Valentina is distributed in the hope that it will be useful,
44  ** but WITHOUT ANY WARRANTY; without even the implied warranty of
45  ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
46  ** GNU General Public License for more details.
47  **
48  ** You should have received a copy of the GNU General Public License
49  ** along with Valentina. if not, see <http://www.gnu.org/licenses/>.
50  **
51  *************************************************************************/
52 
53 #include "pattern_piece_dialog.h"
54 #include "ui_pattern_piece_dialog.h"
55 
56 #include "dialoginternalpath.h"
57 #include "vpointf.h"
60 #include "../ifc/xml/vlabeltemplateconverter.h"
61 #include "../vformat/vlabeltemplate.h"
62 #include "../vmisc/logging.h"
63 #include "../vmisc/vcommonsettings.h"
64 #include "../vpatterndb/calculator.h"
65 #include "../vpatterndb/vpiecenode.h"
66 #include "../vpatterndb/vpiecepath.h"
67 #include "../../support/edit_formula_dialog.h"
68 #include "../../support/editlabeltemplate_dialog.h"
69 #include "../../../tools/pattern_piece_tool.h"
70 #include "../../../undocommands/savepiecepathoptions.h"
71 
72 #include <QColorDialog>
73 #include <QFileInfo>
74 #include <QGuiApplication>
75 #include <QKeyEvent>
76 #include <QMenu>
77 #include <QPixmap>
78 #include <QScreen>
79 #include <QSound>
80 #include <QTimer>
81 #include <QtNumeric>
82 
83 Q_LOGGING_CATEGORY(pattern_piece_dialog, "pattern_piece_dialog")
84 
85 namespace
86 {
87 //---------------------------------------------------------------------------------------------------------------------
88 void enableDefaultButton(QPushButton *defButton, const QString &formula)
89 {
90  SCASSERT(defButton != nullptr)
91 
92  if (formula != currentSeamAllowance)
93  {
94  defButton->setEnabled(true);
95  }
96 }
97 
98 //---------------------------------------------------------------------------------------------------------------------
99 QString getFormulaFromUser(QPlainTextEdit *textEdit)
100 {
101  SCASSERT(textEdit != nullptr)
102 
103  QString formula = textEdit->toPlainText();
104  formula.replace("\n", " ");
105  return qApp->TrVars()->TryFormulaFromUser(formula, qApp->Settings()->GetOsSeparator());
106 }
107 }
108 
109 //---------------------------------------------------------------------------------------------------------------------
110 PatternPieceDialog::PatternPieceDialog(const VContainer *data, const quint32 &toolId, QWidget *parent)
111  : DialogTool(data, toolId, parent)
112  , ui(new Ui::PatternPieceDialog)
113  , applyAllowed(false)// By default disabled
114  , flagGrainlineAnchor(true)
115  , flagPieceLabelAnchor(true)
116  , flagPatternLabelAnchor(true)
117  , flagGrainlineFormula(true)
118  , flagPieceLabelAngle(true)
119  , flagPieceLabelFormula(true)
120  , flagPatternLabelAngle(true)
121  , flagPatternLabelFormula(true)
122  , flagBeforeFormula(true)
123  , flagAfterFormula(true)
124  , flagMainPath(true)
125  , m_bAddMode(true)
126  , m_mx(0)
127  , m_my(0)
128  , m_inLayout(true)
129  , m_isLocked(false)
130  , m_dialog()
131  , m_anchorPoints()
132  , m_oldData()
133  , m_oldGeom()
134  , m_oldGrainline()
135  , m_rotationBaseHeight(0)
136  , m_lengthBaseHeight(0)
137  , m_pieceLabelWidthBaseHeight(0)
138  , m_pieceLabelHeightBaseHeight(0)
139  , m_pieceLabelAngleBaseHeight(0)
140  , m_patternLabelWidthBaseHeight(0)
141  , m_patternLabelHeightBaseHeight(0)
142  , m_patternLabelAngleBaseHeight(0)
143  , m_widthFormula(0)
144  , m_beforeWidthFormula(0)
145  , m_afterWidthFormula(0)
146  , m_timerWidth(nullptr)
147  , m_timerWidthBefore(nullptr)
148  , m_timerWidthAfter(nullptr)
149  , m_saWidth(0)
150  , m_patternLabelLines()
151  , m_pieceLabelLines()
152  , m_beep(new QSound(qApp->Settings()->getSelectionSound()))
153 {
154  ui->setupUi(this);
155  setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
156  setWindowIcon(QIcon(":/toolicon/32x32/new_piece.png"));
157 
158  //Limit dialog height to 80% of screen size
159  setMaximumHeight(qRound(QGuiApplication::primaryScreen()->availableGeometry().height() * .8));
160 
163 
172 
173  flagName = true;
174  ChangeColor(ui->editName_Label, okColor);
176  CheckState();
177 
178  if (!applyAllowed && vis.isNull())
179  {
180  vis = new PatternPieceVisual(data);
181  }
182 
183  // Always show Properties page on start.
184  ui->pages_StackedWidget->setCurrentIndex(TabOrder::Properties);
185  ui->menuTab_ListWidget->setCurrentRow(TabOrder::Properties);
186 
187  connect(ui->menuTab_ListWidget, &QListWidget::currentItemChanged, this, &PatternPieceDialog::pageChanged);
188 }
189 
190 //---------------------------------------------------------------------------------------------------------------------
192 {
193  delete m_anchorPoints;
194  delete ui;
195 }
196 
197 //---------------------------------------------------------------------------------------------------------------------
198 void PatternPieceDialog::pageChanged(QListWidgetItem *current, QListWidgetItem *previous)
199 {
200  if (current == nullptr)
201  {
202  current = previous;
203  }
204  int rowIndex = ui->menuTab_ListWidget->row(current);
205  ui->pages_StackedWidget->setCurrentIndex(rowIndex);
206 
207  if (rowIndex == TabOrder::Labels || rowIndex == TabOrder::AnchorPoints || rowIndex == TabOrder::Grainline)
208  {
210  }
211  else
212  {
213  if (!m_anchorPoints.isNull())
214  {
215  delete m_anchorPoints;
216  }
217  }
218 }
219 
220 //---------------------------------------------------------------------------------------------------------------------
222 {
223  SCASSERT(apply_Button != nullptr);
224  apply_Button->setEnabled(enable);
225  applyAllowed = enable;
226 
227  ui->internalPaths_Tab->setEnabled(applyAllowed);
228  if (applyAllowed == true)
229  {
230  qCDebug(pattern_piece_dialog, "PatternPieceDialog applyAllowed = True");
231  for (int i = TabOrder::SeamAllowance; i < TabOrder::Count; ++i)
232  {
233  auto flags = ui->menuTab_ListWidget->item(i)->flags();
234  ui->menuTab_ListWidget->item(i)->setFlags(flags | Qt::ItemIsEnabled);
235  }
236  }
237  else
238  {
239  qCDebug(pattern_piece_dialog, "PatternPieceDialog applyAllowed = False");
240  for (int i = TabOrder::SeamAllowance; i < TabOrder::Count; ++i)
241  {
242  auto flags = ui->menuTab_ListWidget->item(i)->flags();
243  ui->menuTab_ListWidget->item(i)->setFlags(flags & ~Qt::ItemIsEnabled);
244  }
245  }
246 }
247 
248 //---------------------------------------------------------------------------------------------------------------------
250 {
251  return CreatePiece();
252 }
253 
254 //---------------------------------------------------------------------------------------------------------------------
256 {
257  ui->mainPath_ListWidget->clear();
258  for (int i = 0; i < piece.GetPath().CountNodes(); ++i)
259  {
260  newMainPathItem(piece.GetPath().at(i));
261  }
262 
263  ui->hideSeamLine_CheckBox->setChecked(piece.isHideSeamLine());
264  ui->customSeamAllowance_ListWidget->blockSignals(true);
265  ui->customSeamAllowance_ListWidget->clear();
266  for (int i = 0; i < piece.GetCustomSARecords().size(); ++i)
267  {
269  }
270  ui->customSeamAllowance_ListWidget->blockSignals(false);
271 
272  ui->internalPaths_ListWidget->clear();
273  for (int i = 0; i < piece.GetInternalPaths().size(); ++i)
274  {
275  newInternalPath(piece.GetInternalPaths().at(i));
276  }
277 
278  ui->anchorPoints_ListWidget->clear();
279  for (int i = 0; i < piece.getAnchors().size(); ++i)
280  {
281  newAnchorPoint(piece.getAnchors().at(i));
282  }
283 
285 
286  ui->startPoint_ComboBox->blockSignals(true);
287  ui->startPoint_ComboBox->clear();
288  ui->startPoint_ComboBox->blockSignals(false);
289 
290  ui->endPoint_ComboBox->blockSignals(true);
291  ui->endPoint_ComboBox->clear();
292  ui->endPoint_ComboBox->blockSignals(false);
293 
295 
296  ui->forbidFlipping_CheckBox->setChecked(piece.IsForbidFlipping());
297  ui->seams_CheckBox->setChecked(piece.IsSeamAllowance());
298  ui->builtIn_CheckBox->setChecked(piece.IsSeamAllowanceBuiltIn());
299  ui->pieceName_LineEdit->setText(piece.GetName());
300  setPieceColor(piece.getColor());
301  setPieceFill(piece.getFill());
302  setInLayout(piece.isInLayout());
303  setPieceLock(piece.isLocked());
304 
305  const QString width = qApp->TrVars()->FormulaToUser(piece.getSeamAllowanceWidthFormula(), qApp->Settings()->GetOsSeparator());
306  ui->widthFormula_PlainTextEdit->setPlainText(width);
307  m_saWidth = piece.GetSAWidth();
308 
309  m_mx = piece.GetMx();
310  m_my = piece.GetMy();
311 
312  m_oldData = piece.GetPatternPieceData();
313  ui->letter_LineEdit->setText(m_oldData.GetLetter());
314  ui->annotation_LineEdit->setText(m_oldData.GetAnnotation());
315  ui->orientation_ComboBox->setCurrentText(m_oldData.GetOrientation());
316  ui->rotation_ComboBox->setCurrentText(m_oldData.GetRotationWay());
317  ui->tilt_ComboBox->setCurrentText(m_oldData.GetTilt());
318  ui->foldPosition_ComboBox->setCurrentText(m_oldData.GetFoldPosition());
319 
320  ui->quantity_SpinBox->setValue(m_oldData.GetQuantity());
321  ui->fold_CheckBox->setChecked(m_oldData.IsOnFold());
323 
324  ui->arrow_ComboBox->setCurrentIndex(int(piece.GetGrainlineGeometry().GetArrowType()));
325 
326  ui->pieceLabel_GroupBox->setChecked(m_oldData.IsVisible());
327  ChangeCurrentData(ui->pieceLabelCenterAnchor_ComboBox, m_oldData.centerAnchorPoint());
328  ChangeCurrentData(ui->pieceLabelTopLeftAnchor_ComboBox, m_oldData.topLeftAnchorPoint());
329  ChangeCurrentData(ui->pieceLabelBottomRightAnchor_ComboBox, m_oldData.bottomRightAnchorPoint());
333 
334  m_oldGeom = piece.GetPatternInfo();
335  ui->patternLabel_GroupBox->setChecked(m_oldGeom.IsVisible());
336  ChangeCurrentData(ui->patternLabelCenterAnchor_ComboBox, m_oldGeom.centerAnchorPoint());
337  ChangeCurrentData(ui->patternLabelTopLeftAnchor_ComboBox, m_oldGeom.topLeftAnchorPoint());
338  ChangeCurrentData(ui->patternLabelBottomRightAnchor_ComboBox, m_oldGeom.bottomRightAnchorPoint());
342 
344  ui->grainline_GroupBox->setChecked(m_oldGrainline.IsVisible());
345  ChangeCurrentData(ui->grainlineCenterAnchor_ComboBox, m_oldGrainline.centerAnchorPoint());
346  ChangeCurrentData(ui->grainlineTopAnchor_ComboBox, m_oldGrainline.topAnchorPoint());
347  ChangeCurrentData(ui->grainlineBottomAnchor_ComboBox, m_oldGrainline.bottomAnchorPoint());
350 
355 
356  nodeListChanged();
357 }
358 
359 //---------------------------------------------------------------------------------------------------------------------
360 /**
361 * @brief ChosenObject adds selected object of id and type to list of path items.
362 * @param id id of object (points, arcs, splines, spline paths)
363 * @param type type of scene object
364  */
365 void PatternPieceDialog::ChosenObject(quint32 id, const SceneObject &type)
366 {
367  if (!prepare)
368  {
369  bool reverse = false;
370  const QSharedPointer<VGObject> obj = data->GetGObject(id);
371  const GOType objType = static_cast<GOType>(obj->getType());
372  quint32 previousId = getPreviousId();
373 
374  if (objType != GOType::Point && objType != GOType::Unknown)
375  {
376  if (QGuiApplication::keyboardModifiers() == Qt::ShiftModifier)
377  {
378  reverse = true;
379  }
380  else if (QGuiApplication::keyboardModifiers() == Qt::ControlModifier)
381  {
382  reverse = false;
383  }
384  else if (previousId == NULL_ID)
385  {
386  reverse = false;
387  }
388  else if (previousId != NULL_ID)
389  {
390  QPointF previousPoint;
391  const QSharedPointer<VGObject> previousObj = data->GetGObject(previousId);
392  const GOType previousObjType = static_cast<GOType>(previousObj->getType());
393  if (previousObjType == GOType::Point)
394  {
395  previousPoint = static_cast<QPointF>(*data->GeometricObject<VPointF>(previousId));
396  }
397  else
398  {
400  getLastNode().GetReverse() ? previousPoint = curve->getFirstPoint()
401  : previousPoint = curve->getLastPoint();
402  }
403 
405  if (curve->isPointOnCurve(previousPoint) &&
406  curve->getFirstPoint() != previousPoint &&
407  curve->getLastPoint() != previousPoint)
408  {
409  QList<QListWidgetItem *> items = ui->mainPath_ListWidget->findItems(curve->name(),
410  Qt::MatchContains);
411 
412  if (!items.isEmpty())
413  {
414  VPieceNode rowNode = qvariant_cast<VPieceNode>(items[0]->data(Qt::UserRole));
415  reverse = rowNode.GetReverse();
416  }
417  }
418  else if (curve->getFirstPoint() != previousPoint)
419  {
420  reverse = true;
421  }
422  }
423  else
424  {
427  QVector<QPointF> curvePoints = curve->getPoints();
428  points.append(curvePoints);
429  reverse = !VPiece::isClockwise(points);
430  }
431  }
432 
433  if (id != previousId)
434  {
435  switch (type)
436  {
437  case SceneObject::Arc:
439  m_beep->play();
440  break;
441  case SceneObject::ElArc:
443  m_beep->play();
444  break;
445  case SceneObject::Point:
447  m_beep->play();
448  break;
449  case SceneObject::Spline:
451  m_beep->play();
452  break;
455  m_beep->play();
456  break;
457  case (SceneObject::Line):
458  case (SceneObject::Piece):
459  case (SceneObject::Unknown):
460  default:
461  qDebug() << "Invalid scene object. Ignore.";
462  break;
463  }
464  }
465  else
466  {
467  if (ui->mainPath_ListWidget->count() > 1)
468  {
469  QApplication::beep();
470  delete getItemById(id);
471  }
472  }
473 
475 
476  if (!applyAllowed)
477  {
478  auto visPath = qobject_cast<PatternPieceVisual *>(vis);
479  SCASSERT(visPath != nullptr);
480  const VPiece p = CreatePiece();
481  visPath->SetPiece(p);
482 
483  if (p.GetPath().CountNodes() == 1)
484  {
485  emit ToolTip(tr("Select main path objects clockwise, Use <b>SHIFT</b> to reverse curve direction, "
486  " or <b>CTRL</b> to keep curve direction. "
487  "Press <b>ENTER</b> to finish piece creation "));
488 
489  if (!qApp->getCurrentScene()->items().contains(visPath))
490  {
491  visPath->VisualMode(NULL_ID);
492  }
493  else
494  {
495  visPath->RefreshGeometry();
496  }
497  }
498  else
499  {
500  visPath->RefreshGeometry();
501  }
502  }
503  }
504 }
505 
506 //---------------------------------------------------------------------------------------------------------------------
508 {
509  if (click == false)
510  {
511  emit ToolTip("");
512  prepare = true;
513 
514  if (!applyAllowed)
515  {
516  auto visPath = qobject_cast<PatternPieceVisual *>(vis);
517  SCASSERT(visPath != nullptr);
518  visPath->SetMode(Mode::Show);
519  visPath->RefreshGeometry();
520  }
521 
522  // Fix issue #526. Dialog Detail is not on top after selection second object on Mac.
523  setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint);
524  show();
525  }
526 }
527 
528 //---------------------------------------------------------------------------------------------------------------------
530 {}
531 
532 //---------------------------------------------------------------------------------------------------------------------
534 {
535  SCASSERT(ok_Button != nullptr);
536  SCASSERT(apply_Button != nullptr);
537  ok_Button->setEnabled(flagName
538  && flagFormula
539  && flagMainPath
543 
544  if (applyAllowed)
545  {
546  ok_Button->setEnabled(ok_Button->isEnabled() && flagBeforeFormula && flagAfterFormula);
547  apply_Button->setEnabled(ok_Button->isEnabled()); // In case dialog does not have an apply button
548  }
549 
551  {
552  clearErrorText(TabOrder::SeamAllowance, tr("Seam Allowance "));
553  }
554  else
555  {
556  setErrorText(TabOrder::SeamAllowance, tr("Seam Allowance"));
557  }
558 
559  if (flagMainPath)
560  {
561  clearErrorText(TabOrder::Paths, tr("Paths "));
562  QString tooltip = tr("Ready!");
563  if (!applyAllowed)
564  {
565  tooltip = tooltip + QLatin1String(" <b>") +
566  tr("Press OK to create pattern piece") + QLatin1String("</b>");
567  }
568  ui->status_Label->setText(tooltip);
569  }
570  else
571  {
572  setErrorText(TabOrder::Paths, tr("Paths"));
573  }
574 
575 }
576 
578 {
579  ui->menuTab_ListWidget->item(tab)->setText(text + QLatin1String("*"));
580 }
581 
583 {
584  ui->menuTab_ListWidget->item(tab)->setText(text);
585 }
586 
587 //---------------------------------------------------------------------------------------------------------------------
588 /*
589  * @brief Filters keyboard event to check if the a key was pressed.
590  * @param object QObject that sent the event.
591  * @param event QEvent.
592  * @return if the node list was the sending object:
593  * True if the key(s) pressed makes up a shortcut sequence of a context menu item.
594  * False if any other key.
595  * if event sent by an object other than the main path list widget pass the event on to the parent.
596  */
597 bool PatternPieceDialog::eventFilter(QObject *object, QEvent *event)
598 {
599  if (QListWidget *list = qobject_cast<QListWidget *>(object))
600  {
601  if (event->type() == QEvent::KeyPress)
602  {
603  const int row = ui->mainPath_ListWidget->currentRow();
604  if (ui->mainPath_ListWidget->count() <= 0 || row < 0 || row >= ui->mainPath_ListWidget->count())
605  {
606  return false;
607  }
608  QListWidgetItem *rowItem = list->item(row);
609  SCASSERT(rowItem != nullptr);
610 
611  QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
612 
613  if (keyEvent->key() == Qt::Key_Delete)
614  {
615  delete rowItem;
616  return true;
617  }
618  if (keyEvent->modifiers() & Qt::ControlModifier)
619  {
620  switch (keyEvent->key())
621  {
622  case Qt::Key_R:
623  {
624  reverseNode(rowItem);
625  return true;
626  }
627  case Qt::Key_D:
628  {
629  duplicateNode(rowItem);
630  return true;
631  }
632  case Qt::Key_E:
633  {
634  excludeNode(rowItem);
635  return true;
636  }
637  }
638  }
639  else if (keyEvent->modifiers() & Qt::ShiftModifier)
640  {
641  switch (keyEvent->key())
642  {
643  case Qt::Key_X:
644  {
645  setNotch(rowItem, false, NotchType::Slit);
646  return true;
647  }
648  case Qt::Key_S:
649  {
650  setNotch(rowItem, true, NotchType::Slit);
651  return true;
652  }
653  case Qt::Key_T:
654  {
655  setNotch(rowItem, true, NotchType::TNotch);
656  return true;
657  }
658  case Qt::Key_U:
659  {
660  setNotch(rowItem, true, NotchType::UNotch);
661  return true;
662  }
663  case Qt::Key_I:
664  {
665  setNotch(rowItem, true, NotchType::VInternal);
666  return true;
667  }
668  case Qt::Key_E:
669  {
670  setNotch(rowItem, true, NotchType::VExternal);
671  return true;
672  }
673  case Qt::Key_C:
674  {
675  setNotch(rowItem, true, NotchType::Castle);
676  return true;
677  }
678  case Qt::Key_D:
679  {
680  setNotch(rowItem, true, NotchType::Diamond);
681  return true;
682  }
683  }
684  }
685  }
686  }
687  else
688  {
689  return DialogTool::eventFilter(object, event); // pass the event on to the parent class
690  }
691  return false; // pass the event to the widget
692 }
693 
694 //---------------------------------------------------------------------------------------------------------------------
695 void PatternPieceDialog::closeEvent(QCloseEvent *event)
696 {
697  ui->widthFormula_PlainTextEdit->blockSignals(true);
698  ui->beforeWidthFormula_PlainTextEdit->blockSignals(true);
699  ui->afterWidthFormula_PlainTextEdit->blockSignals(true);
700  ui->rotationFormula_LineEdit->blockSignals(true);
701  ui->lengthFormula_LineEdit->blockSignals(true);
702  DialogTool::closeEvent(event);
703 }
704 
705 //---------------------------------------------------------------------------------------------------------------------
706 void PatternPieceDialog::showEvent(QShowEvent *event)
707 {
708  QDialog::showEvent(event);
709  if (isInitialized || event->spontaneous())
710  {
711  return;
712  }
713 
714  const QSize size = qApp->Settings()->getPatternPieceDialogSize();
715  if (!size.isEmpty())
716  {
717  resize(size);
718  }
719 
720  isInitialized = true;//first show windows are held
721 }
722 
723 //---------------------------------------------------------------------------------------------------------------------
724 void PatternPieceDialog::resizeEvent(QResizeEvent *event)
725 {
726  // Remember the size for the next time this dialog is opened, but only
727  // if the dialog was already initialized.
728  if (isInitialized)
729  {
730  qApp->Settings()->setPatternPieceDialogSize(size());
731  }
732  DialogTool::resizeEvent(event);
733 }
734 
735 //---------------------------------------------------------------------------------------------------------------------
737 {
738  QLineEdit *name = qobject_cast<QLineEdit*>(sender());
739  if (name)
740  {
741  if (name->text().isEmpty())
742  {
743  flagName = false;
744  ChangeColor(ui->editName_Label, Qt::red);
745  setErrorText(TabOrder::Properties, tr("Properties"));
746  }
747  else
748  {
749  flagName = true;
750  ChangeColor(ui->editName_Label, okColor);
751  clearErrorText(TabOrder::Properties, tr("Properties "));
752  }
753  }
754  CheckState();
755 }
756 
757 //---------------------------------------------------------------------------------------------------------------------
759 {
760  const QColor color = QColorDialog::getColor(Qt::white, this, "Select Color", QColorDialog::DontUseNativeDialog);
761 
762  if (color.isValid())
763  {
764  ui->color_Label->setText(color.name());
765  ui->color_Label->setPalette(QPalette(color));
766  CheckState();
767  }
768 }
769 
770 //---------------------------------------------------------------------------------------------------------------------
772 {
773  const int row = ui->mainPath_ListWidget->currentRow();
774  if (ui->mainPath_ListWidget->count() == 0 || row == -1 || row >= ui->mainPath_ListWidget->count())
775  {
776  return;
777  }
778 
779  // workaround for https://bugreports.qt.io/browse/QTBUG-97559: assign parent to QMenu
780  QScopedPointer<QMenu> menu(new QMenu(ui->mainPath_ListWidget));
781  NodeInfo info;
782  NotchType notchType = NotchType::Slit;
783  bool isNotch = false;
784  QListWidgetItem *rowItem = ui->mainPath_ListWidget->item(row);
785  SCASSERT(rowItem != nullptr);
786  VPieceNode rowNode = qvariant_cast<VPieceNode>(rowItem->data(Qt::UserRole));
787 
788  QAction *actionNotch = nullptr;
789  QAction *actionNone = nullptr;
790  QAction *actionSlit = nullptr;
791  QAction *actionTNotch = nullptr;
792  QAction *actionUNotch = nullptr;
793  QAction *actionVInternal = nullptr;
794  QAction *actionVExternal = nullptr;
795  QAction *actionCastle = nullptr;
796  QAction *actionDiamond = nullptr;
797 
798  QAction *actionReverse = nullptr;
799  QAction *actionDuplicate = nullptr;
800 
801  if (rowNode.GetTypeTool() != Tool::NodePoint)
802  {
803  actionReverse = menu->addAction(tr("Reverse") + QStringLiteral("\tCtrl + R"));
804  actionReverse->setCheckable(true);
805  actionReverse->setChecked(rowNode.GetReverse());
806 
807  actionDuplicate = menu->addAction(tr("Duplicate") + QStringLiteral("\tCtrl + D"));
808  }
809  else
810  {
811  QMenu *notchMenu = menu->addMenu(tr("Notch"));
812  actionNotch = notchMenu->menuAction();
813  actionNotch->setCheckable(true);
814  actionNotch->setChecked(rowNode.isNotch());
815 
816  actionNone = notchMenu->addAction( tr("None") + QStringLiteral("\tShift + X"));
817  actionSlit = notchMenu->addAction(QIcon("://icon/24x24/slit_notch.png"), tr("Slit") + QStringLiteral("\tShift + S"));
818  actionTNotch = notchMenu->addAction(QIcon("://icon/24x24/t_notch.png"), tr("TNotch") + QStringLiteral("\tShift + T"));
819  actionUNotch = notchMenu->addAction(QIcon("://icon/24x24/u_notch.png"), tr("UNotch") + QStringLiteral("\tShift + U"));
820  actionVInternal = notchMenu->addAction(QIcon("://icon/24x24/internal_v_notch.png"), tr("VInternal") + QStringLiteral("\tShift + I"));
821  actionVExternal = notchMenu->addAction(QIcon("://icon/24x24/external_v_notch.png"), tr("VExternal") + QStringLiteral("\tShift + E"));
822  actionCastle = notchMenu->addAction(QIcon("://icon/24x24/castle_notch.png"), tr("Castle") + QStringLiteral("\tShift + C"));
823  actionDiamond = notchMenu->addAction(QIcon("://icon/24x24/diamond_notch.png"), tr("Diamond") + QStringLiteral("\tShift + D"));
824  }
825 
826  QAction *actionExcluded = menu->addAction(tr("Excluded") + QStringLiteral("\tCtrl + E"));
827  actionExcluded->setCheckable(true);
828  actionExcluded->setChecked(rowNode.isExcluded());
829 
830  QAction *actionDelete = menu->addAction(QIcon::fromTheme("edit-delete"), tr("Delete") + QStringLiteral("\tDel"));
831 
832  QAction *selectedAction = menu->exec(ui->mainPath_ListWidget->viewport()->mapToGlobal(pos));
833  if (selectedAction == actionDelete)
834  {
835  delete ui->mainPath_ListWidget->item(row);
836  }
837  else if (rowNode.GetTypeTool() != Tool::NodePoint && selectedAction == actionReverse)
838  {
839  reverseNode(rowItem);
840  }
841  else if (rowNode.GetTypeTool() != Tool::NodePoint && selectedAction == actionDuplicate)
842  {
843  duplicateNode(rowItem);
844  }
845  else if (selectedAction == actionExcluded)
846  {
847  excludeNode(rowItem);
848  }
849  else
850  {
851  if (selectedAction == actionNone)
852  {
853  isNotch = false;
854  notchType = NotchType::Slit;
855  }
856  else if (selectedAction == actionSlit)
857  {
858  isNotch = true;
859  notchType = NotchType::Slit;
860  }
861  else if (selectedAction == actionTNotch)
862  {
863  isNotch = true;
864  notchType = NotchType::TNotch;
865  }
866  else if (selectedAction == actionUNotch)
867  {
868  isNotch = true;
869  notchType = NotchType::UNotch;
870  }
871  else if (selectedAction == actionVInternal)
872  {
873  isNotch = true;
874  notchType = NotchType::VInternal;
875  }
876  else if (selectedAction == actionVExternal)
877  {
878  isNotch = true;
879  notchType = NotchType::VExternal;
880  }
881  else if (selectedAction == actionCastle)
882  {
883  isNotch = true;
884  notchType = NotchType::Castle;
885  }
886  else if (selectedAction == actionDiamond)
887  {
888  isNotch = true;
889  notchType = NotchType::Diamond;
890  }
891 
892  setNotch(rowItem, isNotch, notchType);
893  }
894 
896  nodeListChanged();
897 }
898 
899 //---------------------------------------------------------------------------------------------------------------------
901 {
902  const int row = ui->customSeamAllowance_ListWidget->currentRow();
903  if (ui->customSeamAllowance_ListWidget->count() == 0 || row == -1 || row >= ui->customSeamAllowance_ListWidget->count())
904  {
905  return;
906  }
907 
908  // workaround for https://bugreports.qt.io/browse/QTBUG-97559: assign parent to QMenu
909  QScopedPointer<QMenu> menu(new QMenu(ui->customSeamAllowance_ListWidget));
910  QAction *actionOption = menu->addAction(QIcon::fromTheme("preferences-other"), tr("Options"));
911 
912  QListWidgetItem *rowItem = ui->customSeamAllowance_ListWidget->item(row);
913  SCASSERT(rowItem != nullptr);
914  CustomSARecord record = qvariant_cast<CustomSARecord>(rowItem->data(Qt::UserRole));
915 
916  QAction *actionReverse = menu->addAction(tr("Reverse"));
917  actionReverse->setCheckable(true);
918  actionReverse->setChecked(record.reverse);
919 
920  QAction *actionDelete = menu->addAction(QIcon::fromTheme("edit-delete"), tr("Delete"));
921 
922  QAction *selectedAction = menu->exec(ui->customSeamAllowance_ListWidget->viewport()->mapToGlobal(pos));
923  if (selectedAction == actionDelete)
924  {
925  delete ui->customSeamAllowance_ListWidget->item(row);
926  }
927  else if (selectedAction == actionReverse)
928  {
929  record.reverse = !record.reverse;
930  rowItem->setData(Qt::UserRole, QVariant::fromValue(record));
931  rowItem->setText(getPathName(record.path, record.reverse));
932  }
933  else if (selectedAction == actionOption)
934  {
935  auto *dialog = new DialogInternalPath(data, record.path, this);
936  dialog->SetPiecePath(data->GetPiecePath(record.path));
937  dialog->SetPieceId(toolId);
939  {
940  dialog->setSeamAllowanceWidthFormula(getSeamAllowanceWidthFormula());
941  }
942  dialog->EnbleShowMode(true);
943  m_dialog = dialog;
944  m_dialog->setModal(true);
946  m_dialog->show();
947  }
948 }
949 
950 //---------------------------------------------------------------------------------------------------------------------
952 {
953  const int row = ui->internalPaths_ListWidget->currentRow();
954  if (ui->internalPaths_ListWidget->count() == 0 || row == -1
955  || row >= ui->internalPaths_ListWidget->count())
956  {
957  return;
958  }
959 
960  // workaround for https://bugreports.qt.io/browse/QTBUG-97559: assign parent to QMenu
961  QScopedPointer<QMenu> menu(new QMenu(ui->internalPaths_ListWidget));
962  QAction *actionOption = menu->addAction(QIcon::fromTheme("preferences-other"), tr("Options"));
963  QAction *actionDelete = menu->addAction(QIcon::fromTheme("edit-delete"), tr("Delete"));
964 
965  QAction *selectedAction = menu->exec(ui->internalPaths_ListWidget->viewport()->mapToGlobal(pos));
966  if (selectedAction == actionDelete)
967  {
968  delete ui->internalPaths_ListWidget->item(row);
969  }
970  else if (selectedAction == actionOption)
971  {
972  QListWidgetItem *rowItem = ui->internalPaths_ListWidget->item(row);
973  SCASSERT(rowItem != nullptr);
974  const quint32 pathId = qvariant_cast<quint32>(rowItem->data(Qt::UserRole));
975 
976  auto *dialog = new DialogInternalPath(data, pathId, this);
977  dialog->SetPiecePath(data->GetPiecePath(pathId));
978  dialog->SetPieceId(toolId);
979  dialog->EnbleShowMode(true);
980  m_dialog = dialog;
981  m_dialog->setModal(true);
983  m_dialog->show();
984  }
985 }
986 
987 //---------------------------------------------------------------------------------------------------------------------
989 {
990  const int row = ui->anchorPoints_ListWidget->currentRow();
991  if (ui->anchorPoints_ListWidget->count() == 0 || row == -1 || row >= ui->anchorPoints_ListWidget->count())
992  {
993  return;
994  }
995 
996  // workaround for https://bugreports.qt.io/browse/QTBUG-97559: assign parent to QMenu
997  QScopedPointer<QMenu> menu(new QMenu(ui->anchorPoints_ListWidget));
998  QAction *actionDelete = menu->addAction(QIcon::fromTheme("edit-delete"), tr("Delete"));
999 
1000  QAction *selectedAction = menu->exec(ui->anchorPoints_ListWidget->viewport()->mapToGlobal(pos));
1001  if (selectedAction == actionDelete)
1002  {
1003  delete ui->anchorPoints_ListWidget->item(row);
1005  }
1006 }
1007 
1008 //---------------------------------------------------------------------------------------------------------------------
1010 {
1011  if (!applyAllowed)
1012  {
1013  auto visPath = qobject_cast<PatternPieceVisual *>(vis);
1014  SCASSERT(visPath != nullptr);
1015  visPath->SetPiece(CreatePiece());
1016  visPath->RefreshGeometry();
1017  }
1020  customSeamAllowanceChanged(ui->customSeamAllowance_ListWidget->currentRow());
1022 }
1023 
1024 //---------------------------------------------------------------------------------------------------------------------
1026 {
1027  ui->builtIn_CheckBox->setEnabled(enable);
1028  ui->hideSeamLine_CheckBox->setEnabled(enable);
1029 
1030  if (!enable)
1031  {
1032  ui->automatic_GroupBox->setEnabled(enable);
1033  ui->custom_GroupBox->setEnabled(enable);
1034  }
1035  else
1036  {
1037  ui->builtIn_CheckBox->toggled(ui->builtIn_CheckBox->isChecked());
1038  }
1039 }
1040 
1041 //---------------------------------------------------------------------------------------------------------------------
1043 {
1044  ui->automatic_GroupBox->setEnabled(!enable);
1045  ui->custom_GroupBox->setEnabled(!enable);
1046 
1047  if (enable)
1048  {
1050  }
1051 }
1052 
1053 //---------------------------------------------------------------------------------------------------------------------
1055 {
1056  ui->beforeWidthFormula_PlainTextEdit->setDisabled(true);
1057  ui->beforeExpr_ToolButton->setDisabled(true);
1058  ui->beforeDefault_PushButton->setDisabled(true);
1059 
1060  ui->afterWidthFormula_PlainTextEdit->setDisabled(true);
1061  ui->afterExpr_ToolButton->setDisabled(true);
1062  ui->afterDefault_PushButton->setDisabled(true);
1063 
1064  ui->angle_ComboBox->setDisabled(true);
1065 
1066  ui->angle_ComboBox->blockSignals(true);
1067 
1068  if (index != -1)
1069  {
1070  const VPiece piece = CreatePiece();
1071  const int nodeIndex = piece.GetPath().indexOfNode(ui->nodes_ComboBox->currentData().toUInt());
1072  if (nodeIndex != -1)
1073  {
1074  const VPieceNode &node = piece.GetPath().at(nodeIndex);
1075 
1076  // Seam allowance before node
1077  ui->beforeWidthFormula_PlainTextEdit->setEnabled(true);
1078  ui->beforeExpr_ToolButton->setEnabled(true);
1079 
1080  QString w1Formula = node.GetFormulaSABefore();
1081  enableDefaultButton(ui->beforeDefault_PushButton, w1Formula);
1082  w1Formula = qApp->TrVars()->FormulaToUser(w1Formula, qApp->Settings()->GetOsSeparator());
1083 
1084  //Increase textedit box height if needed.
1085  if (w1Formula.length() > 80)
1086  {
1088  }
1089  ui->beforeWidthFormula_PlainTextEdit->setPlainText(w1Formula);
1090  MoveCursorToEnd(ui->beforeWidthFormula_PlainTextEdit);
1091 
1092  // Seam allowance after node
1093  ui->afterWidthFormula_PlainTextEdit->setEnabled(true);
1094  ui->afterExpr_ToolButton->setEnabled(true);
1095 
1096  QString w2Formula = node.GetFormulaSAAfter();
1097  enableDefaultButton(ui->afterDefault_PushButton, w2Formula);
1098  w2Formula = qApp->TrVars()->FormulaToUser(w2Formula, qApp->Settings()->GetOsSeparator());
1099 
1100  //Increase textedit box height if needed.
1101  if (w2Formula.length() > 80)
1102  {
1104  }
1105  ui->afterWidthFormula_PlainTextEdit->setPlainText(w2Formula);
1106  MoveCursorToEnd(ui->afterWidthFormula_PlainTextEdit);
1107 
1108  //Angle type
1109  ui->angle_ComboBox->setEnabled(true);
1110  const int index = ui->angle_ComboBox->findData(static_cast<unsigned char>(node.GetAngleType()));
1111  if (index != -1)
1112  {
1113  ui->angle_ComboBox->setCurrentIndex(index);
1114  }
1115  }
1116  }
1117  else
1118  {
1119  ui->beforeWidthFormula_PlainTextEdit->setPlainText(currentSeamAllowance);
1120  ui->afterWidthFormula_PlainTextEdit->setPlainText(currentSeamAllowance);
1121  ui->angle_ComboBox->setCurrentIndex(-1);
1122  }
1123  ui->angle_ComboBox->blockSignals(false);
1124 }
1125 
1126 //---------------------------------------------------------------------------------------------------------------------
1128 {
1129  ui->slitNotch_RadioButton->setDisabled(true);
1130  ui->tNotch_RadioButton->setDisabled(true);
1131  ui->uNotch_RadioButton->setDisabled(true);
1132  ui->vInternalNotch_RadioButton->setDisabled(true);
1133  ui->vExternalNotch_RadioButton->setDisabled(true);
1134  ui->castleNotch_RadioButton->setDisabled(true);
1135  ui->diamondNotch_RadioButton->setDisabled(true);
1136 
1137  ui->straightforward_RadioButton->setDisabled(true);
1138  ui->bisector_RadioButton->setDisabled(true);
1139  ui->intersection_RadioButton->setDisabled(true);
1140 
1141  ui->showNotch_CheckBox->setDisabled(true);
1142  ui->showNotch_CheckBox->blockSignals(true);
1143 
1144  ui->showSeamlineNotch_CheckBox->setDisabled(true);
1145  ui->showSeamlineNotch_CheckBox->blockSignals(true);
1146 
1147  ui->notchType_GroupBox->blockSignals(true);
1148  ui->notchSubType_GroupBox->blockSignals(true);
1149 
1150  if (index != -1)
1151  {
1152  const VPiece piece = CreatePiece();
1153  const int nodeIndex = piece.GetPath().indexOfNode(ui->notches_ComboBox->currentData().toUInt());
1154  if (nodeIndex != -1)
1155  {
1156  const VPieceNode &node = piece.GetPath().at(nodeIndex);
1157 
1158  // Notch type
1159  ui->slitNotch_RadioButton->setEnabled(true);
1160  ui->tNotch_RadioButton->setEnabled(true);
1161  ui->uNotch_RadioButton->setEnabled(true);
1162  ui->vInternalNotch_RadioButton->setEnabled(true);
1163  ui->vExternalNotch_RadioButton->setEnabled(true);
1164  ui->castleNotch_RadioButton->setEnabled(true);
1165  ui->diamondNotch_RadioButton->setEnabled(true);
1166 
1167  ui->notchAngle_DoubleSpinBox->setEnabled(false);
1168 
1169  switch(node.getNotchType())
1170  {
1171  case NotchType::Slit:
1172  ui->slitNotch_RadioButton->setChecked(true);
1173  ui->notchAngle_DoubleSpinBox->setEnabled(true);
1174  ui->notchAngle_DoubleSpinBox->setValue(node.getNotchAngle());
1175  break;
1176  case NotchType::TNotch:
1177  ui->tNotch_RadioButton->setChecked(true);
1178  break;
1179  case NotchType::UNotch:
1180  ui->uNotch_RadioButton->setChecked(true);
1181  break;
1182  case NotchType::VInternal:
1183  ui->vInternalNotch_RadioButton->setChecked(true);
1184  break;
1185  case NotchType::VExternal:
1186  ui->vExternalNotch_RadioButton->setChecked(true);
1187  break;
1188  case NotchType::Castle:
1189  ui->castleNotch_RadioButton->setChecked(true);
1190  break;
1191  case NotchType::Diamond:
1192  ui->diamondNotch_RadioButton->setChecked(true);
1193  break;
1194  default:
1195  break;
1196  }
1197 
1198  // Notch Sub type
1199  ui->straightforward_RadioButton->setEnabled(true);
1200  ui->bisector_RadioButton->setEnabled(true);
1201  ui->intersection_RadioButton->setEnabled(true);
1202 
1203  switch(node.getNotchSubType())
1204  {
1206  ui->straightforward_RadioButton->setChecked(true);
1207  break;
1209  ui->bisector_RadioButton->setChecked(true);
1210  break;
1212  ui->intersection_RadioButton->setChecked(true);
1213  break;
1214  default:
1215  break;
1216  }
1217 
1218  // Show the seam allowance notch
1219  ui->showNotch_CheckBox->setEnabled(true);
1220  ui->showNotch_CheckBox->setChecked(node.showNotch());
1221 
1222  // Show the seam line notch
1223  ui->showSeamlineNotch_CheckBox->setEnabled(true);
1224  ui->showSeamlineNotch_CheckBox->setChecked(node.showSeamlineNotch());
1225 
1226  ui->notchLength_DoubleSpinBox->setEnabled(true);
1227  ui->notchLength_DoubleSpinBox->setValue(node.getNotchLength());
1228 
1229  ui->notchWidth_DoubleSpinBox->setEnabled(true);
1230  ui->notchWidth_DoubleSpinBox->setValue(node.getNotchWidth());
1231 
1232  ui->notchCount_SpinBox->setEnabled(true);
1233  ui->notchCount_SpinBox->setValue(node.getNotchCount());
1234  }
1235  }
1236 
1237  ui->showNotch_CheckBox->blockSignals(false);
1238  ui->showSeamlineNotch_CheckBox->blockSignals(false);
1239 
1240  ui->notchType_GroupBox->blockSignals(false);
1241  ui->notchSubType_GroupBox->blockSignals(false);
1242 }
1243 
1244 //---------------------------------------------------------------------------------------------------------------------
1246 {
1247  Q_UNUSED(index);
1248 
1249  const int row = ui->customSeamAllowance_ListWidget->currentRow();
1250  if (ui->customSeamAllowance_ListWidget->count() == 0 || row == -1 || row >= ui->customSeamAllowance_ListWidget->count())
1251  {
1252  return;
1253  }
1254 
1255  QListWidgetItem *rowItem = ui->customSeamAllowance_ListWidget->item(row);
1256  SCASSERT(rowItem != nullptr);
1257  CustomSARecord record = qvariant_cast<CustomSARecord>(rowItem->data(Qt::UserRole));
1258  record.startPoint = ui->startPoint_ComboBox->currentData().toUInt();
1259  rowItem->setData(Qt::UserRole, QVariant::fromValue(record));
1260 }
1261 
1262 //---------------------------------------------------------------------------------------------------------------------
1264 {
1265  Q_UNUSED(index);
1266 
1267  const int row = ui->customSeamAllowance_ListWidget->currentRow();
1268  if (ui->customSeamAllowance_ListWidget->count() == 0 || row == -1 || row >= ui->customSeamAllowance_ListWidget->count())
1269  {
1270  return;
1271  }
1272 
1273  QListWidgetItem *rowItem = ui->customSeamAllowance_ListWidget->item(row);
1274  SCASSERT(rowItem != nullptr);
1275  CustomSARecord record = qvariant_cast<CustomSARecord>(rowItem->data(Qt::UserRole));
1276  record.endPoint = ui->endPoint_ComboBox->currentData().toUInt();
1277  rowItem->setData(Qt::UserRole, QVariant::fromValue(record));
1278 }
1279 
1280 //---------------------------------------------------------------------------------------------------------------------
1282 {
1283  Q_UNUSED(index);
1284 
1285  const int row = ui->customSeamAllowance_ListWidget->currentRow();
1286  if (ui->customSeamAllowance_ListWidget->count() == 0 || row == -1 || row >= ui->customSeamAllowance_ListWidget->count())
1287  {
1288  return;
1289  }
1290 
1291  QListWidgetItem *rowItem = ui->customSeamAllowance_ListWidget->item(row);
1292  SCASSERT(rowItem != nullptr);
1293  CustomSARecord record = qvariant_cast<CustomSARecord>(rowItem->data(Qt::UserRole));
1294  record.includeType = static_cast<PiecePathIncludeType>(ui->comboBoxIncludeType->currentData().toUInt());
1295  rowItem->setData(Qt::UserRole, QVariant::fromValue(record));
1296 }
1297 
1298 //---------------------------------------------------------------------------------------------------------------------
1300 {
1301  const int i = ui->nodes_ComboBox->currentIndex();
1302  if (i != -1 && index != -1)
1303  {
1304  QListWidgetItem *rowItem = getItemById(ui->nodes_ComboBox->currentData().toUInt());
1305  if (rowItem)
1306  {
1307  VPieceNode rowNode = qvariant_cast<VPieceNode>(rowItem->data(Qt::UserRole));
1308  rowNode.SetAngleType(static_cast<PieceNodeAngle>(ui->angle_ComboBox->currentData().toUInt()));
1309  rowItem->setData(Qt::UserRole, QVariant::fromValue(rowNode));
1310 
1311  nodeListChanged();
1312  }
1313  }
1314 }
1315 
1316 //---------------------------------------------------------------------------------------------------------------------
1318 {
1319  const QString allowance = qApp->TrVars()->FormulaToUser(currentSeamAllowance, qApp->Settings()->GetOsSeparator());
1320  ui->beforeWidthFormula_PlainTextEdit->setPlainText(allowance);
1321  if (QPushButton *button = qobject_cast<QPushButton*>(sender()))
1322  {
1323  button->setEnabled(false);
1324  }
1325 }
1326 
1327 //---------------------------------------------------------------------------------------------------------------------
1329 {
1330  const QString allowance = qApp->TrVars()->FormulaToUser(currentSeamAllowance, qApp->Settings()->GetOsSeparator());
1331  ui->afterWidthFormula_PlainTextEdit->setPlainText(allowance);
1332  if (QPushButton *button = qobject_cast<QPushButton*>(sender()))
1333  {
1334  button->setEnabled(false);
1335  }
1336 }
1337 
1338 //---------------------------------------------------------------------------------------------------------------------
1340 {
1341  if (ui->customSeamAllowance_ListWidget->count() == 0 || row == -1 || row >= ui->customSeamAllowance_ListWidget->count())
1342  {
1343  ui->startPoint_ComboBox->blockSignals(true);
1344  ui->startPoint_ComboBox->clear();
1345  ui->startPoint_ComboBox->blockSignals(false);
1346 
1347  ui->endPoint_ComboBox->blockSignals(true);
1348  ui->endPoint_ComboBox->clear();
1349  ui->endPoint_ComboBox->blockSignals(false);
1350 
1351  ui->comboBoxIncludeType->blockSignals(true);
1352  ui->comboBoxIncludeType->clear();
1353  ui->comboBoxIncludeType->blockSignals(false);
1354  return;
1355  }
1356 
1357  const QListWidgetItem *item = ui->customSeamAllowance_ListWidget->item(row);
1358  SCASSERT(item != nullptr);
1359  const CustomSARecord record = qvariant_cast<CustomSARecord>(item->data(Qt::UserRole));
1360 
1361  ui->startPoint_ComboBox->blockSignals(true);
1362  initializeCSAPoint(ui->startPoint_ComboBox);
1363  {
1364  const int index = ui->startPoint_ComboBox->findData(record.startPoint);
1365  if (index != -1)
1366  {
1367  ui->startPoint_ComboBox->setCurrentIndex(index);
1368  }
1369  }
1370  ui->startPoint_ComboBox->blockSignals(false);
1371 
1372  ui->endPoint_ComboBox->blockSignals(true);
1373  initializeCSAPoint(ui->endPoint_ComboBox);
1374  {
1375  const int index = ui->endPoint_ComboBox->findData(record.endPoint);
1376  if (index != -1)
1377  {
1378  ui->endPoint_ComboBox->setCurrentIndex(index);
1379  }
1380  }
1381  ui->endPoint_ComboBox->blockSignals(false);
1382 
1383  ui->comboBoxIncludeType->blockSignals(true);
1385  {
1386  const int index = ui->comboBoxIncludeType->findData(static_cast<unsigned char>(record.includeType));
1387  if (index != -1)
1388  {
1389  ui->comboBoxIncludeType->setCurrentIndex(index);
1390  }
1391  }
1392  ui->comboBoxIncludeType->blockSignals(false);
1393 }
1394 
1395 //---------------------------------------------------------------------------------------------------------------------
1397 {
1398  if (result == QDialog::Accepted)
1399  {
1400  SCASSERT(!m_dialog.isNull());
1401  DialogInternalPath *dialog = qobject_cast<DialogInternalPath*>(m_dialog.data());
1402  SCASSERT(dialog != nullptr);
1403  try
1404  {
1405  const VPiecePath newPath = dialog->GetPiecePath();
1406  const VPiecePath oldPath = data->GetPiecePath(dialog->GetToolId());
1407 
1408  SavePiecePathOptions *saveCommand = new SavePiecePathOptions(oldPath, newPath, qApp->getCurrentDocument(),
1409  const_cast<VContainer *>(data),
1410  dialog->GetToolId());
1411  qApp->getUndoStack()->push(saveCommand);
1414  }
1415  catch (const VExceptionBadId &e)
1416  {
1417  qCritical("%s\n\n%s\n\n%s", qUtf8Printable(tr("Error. Can't save piece path.")),
1418  qUtf8Printable(e.ErrorMessage()), qUtf8Printable(e.DetailedInformation()));
1419  }
1420  }
1421  delete m_dialog;
1422 }
1423 
1424 //---------------------------------------------------------------------------------------------------------------------
1426 {
1427  const int i = ui->notches_ComboBox->currentIndex();
1428  if (i != -1)
1429  {
1430  QListWidgetItem *rowItem = getItemById(ui->notches_ComboBox->currentData().toUInt());
1431  if (rowItem)
1432  {
1433  ui->notchAngle_DoubleSpinBox->setEnabled(false);
1434  ui->notchAngle_DoubleSpinBox->setValue(0.0);
1435 
1436  VPieceNode rowNode = qvariant_cast<VPieceNode>(rowItem->data(Qt::UserRole));
1437 
1438  NotchType notchType = stringToNotchType(qApp->Settings()->getDefaultNotchType());
1439 
1440  if (id == ui->notchType_ButtonGroup->id(ui->slitNotch_RadioButton))
1441  {
1442  notchType = NotchType::Slit;
1443  ui->notchAngle_DoubleSpinBox->setEnabled(true);
1444  }
1445  else if (id == ui->notchType_ButtonGroup->id(ui->tNotch_RadioButton))
1446  {
1447  notchType = NotchType::TNotch;
1448  }
1449  else if (id == ui->notchType_ButtonGroup->id(ui->uNotch_RadioButton))
1450  {
1451  notchType = NotchType::UNotch;
1452  }
1453  else if (id == ui->notchType_ButtonGroup->id(ui->vInternalNotch_RadioButton))
1454  {
1455  notchType = NotchType::VInternal;
1456  }
1457  else if (id == ui->notchType_ButtonGroup->id(ui->vExternalNotch_RadioButton))
1458  {
1459  notchType = NotchType::VExternal;
1460  }
1461  else if (id == ui->notchType_ButtonGroup->id(ui->castleNotch_RadioButton))
1462  {
1463  notchType = NotchType::Castle;
1464  }
1465  else if (id == ui->notchType_ButtonGroup->id(ui->diamondNotch_RadioButton))
1466  {
1467  notchType = NotchType::Diamond;
1468  }
1469 
1470  rowNode.setNotchType(notchType);
1471  const NodeInfo info = getNodeInfo(rowNode, true);
1472  rowItem->setData(Qt::UserRole, QVariant::fromValue(rowNode));
1473  rowItem->setIcon(QIcon(info.icon));
1474  rowItem->setText(info.name);
1475 
1476  nodeListChanged();
1477  }
1478  }
1479 }
1480 
1481 //---------------------------------------------------------------------------------------------------------------------
1483 {
1484  const int i = ui->notches_ComboBox->currentIndex();
1485  if (i != -1)
1486  {
1487  QListWidgetItem *rowItem = getItemById(ui->notches_ComboBox->currentData().toUInt());
1488  if (rowItem)
1489  {
1490  VPieceNode rowNode = qvariant_cast<VPieceNode>(rowItem->data(Qt::UserRole));
1491 
1493  if (id == ui->notchSubType_ButtonGroup->id(ui->straightforward_RadioButton))
1494  {
1495  notchSubType = NotchSubType::Straightforward;
1496  }
1497  else if (id == ui->notchSubType_ButtonGroup->id(ui->bisector_RadioButton))
1498  {
1499  notchSubType = NotchSubType::Bisector;
1500  }
1501  else if (id == ui->notchSubType_ButtonGroup->id(ui->intersection_RadioButton))
1502  {
1503  notchSubType = NotchSubType::Intersection;
1504  }
1505 
1506  rowNode.setNotchSubType(notchSubType);
1507  rowItem->setData(Qt::UserRole, QVariant::fromValue(rowNode));
1508 
1509  nodeListChanged();
1510  }
1511  }
1512 }
1513 
1514 //---------------------------------------------------------------------------------------------------------------------
1516 {
1517  const int i = ui->notches_ComboBox->currentIndex();
1518  if (i != -1)
1519  {
1520  QListWidgetItem *rowItem = getItemById(ui->notches_ComboBox->currentData().toUInt());
1521  if (rowItem)
1522  {
1523  VPieceNode rowNode = qvariant_cast<VPieceNode>(rowItem->data(Qt::UserRole));
1524  rowNode.setShowNotch(state);
1525  rowItem->setData(Qt::UserRole, QVariant::fromValue(rowNode));
1526 
1527  nodeListChanged();
1528  }
1529  }
1530 }
1531 
1532 //---------------------------------------------------------------------------------------------------------------------
1534 {
1535  const int i = ui->notches_ComboBox->currentIndex();
1536  if (i != -1)
1537  {
1538  QListWidgetItem *rowItem = getItemById(ui->notches_ComboBox->currentData().toUInt());
1539  if (rowItem)
1540  {
1541  VPieceNode rowNode = qvariant_cast<VPieceNode>(rowItem->data(Qt::UserRole));
1542  rowNode.setShowSeamlineNotch(state);
1543  rowItem->setData(Qt::UserRole, QVariant::fromValue(rowNode));
1544 
1545  nodeListChanged();
1546  }
1547  }
1548 }
1549 
1550 
1551 //---------------------------------------------------------------------------------------------------------------------
1553 {
1554  const int i = ui->notches_ComboBox->currentIndex();
1555  if (i != -1)
1556  {
1557  QListWidgetItem *rowItem = getItemById(ui->notches_ComboBox->currentData().toUInt());
1558  if (rowItem)
1559  {
1560  VPieceNode rowNode = qvariant_cast<VPieceNode>(rowItem->data(Qt::UserRole));
1561  rowNode.setNotchLength(value);
1562  rowItem->setData(Qt::UserRole, QVariant::fromValue(rowNode));
1563 
1564  nodeListChanged();
1565  }
1566  }
1567 
1568 }
1569 
1571 {
1572  ui->notchLength_DoubleSpinBox->setValue(qApp->Settings()->getDefaultNotchLength());
1573 }
1574 
1575 //---------------------------------------------------------------------------------------------------------------------
1577 {
1578  const int i = ui->notches_ComboBox->currentIndex();
1579  if (i != -1)
1580  {
1581  QListWidgetItem *rowItem = getItemById(ui->notches_ComboBox->currentData().toUInt());
1582  if (rowItem)
1583  {
1584  VPieceNode rowNode = qvariant_cast<VPieceNode>(rowItem->data(Qt::UserRole));
1585  rowNode.setNotchWidth(value);
1586  rowItem->setData(Qt::UserRole, QVariant::fromValue(rowNode));
1587 
1588  nodeListChanged();
1589  }
1590  }
1591 
1592 }
1593 
1595 {
1596  ui->notchWidth_DoubleSpinBox->setValue(qApp->Settings()->getDefaultNotchWidth());
1597 }
1598 
1599 //---------------------------------------------------------------------------------------------------------------------
1601 {
1602  const int i = ui->notches_ComboBox->currentIndex();
1603  if (i != -1)
1604  {
1605  QListWidgetItem *rowItem = getItemById(ui->notches_ComboBox->currentData().toUInt());
1606  if (rowItem)
1607  {
1608  VPieceNode rowNode = qvariant_cast<VPieceNode>(rowItem->data(Qt::UserRole));
1609  rowNode.setNotchAngle(value);
1610  rowItem->setData(Qt::UserRole, QVariant::fromValue(rowNode));
1611 
1612  nodeListChanged();
1613  }
1614  }
1615 }
1616 
1618 {
1619  ui->notchAngle_DoubleSpinBox->setValue(0.0);
1620 }
1621 
1622 //---------------------------------------------------------------------------------------------------------------------
1624 {
1625  const int i = ui->notches_ComboBox->currentIndex();
1626  if (i != -1)
1627  {
1628  QListWidgetItem *rowItem = getItemById(ui->notches_ComboBox->currentData().toUInt());
1629  if (rowItem)
1630  {
1631  VPieceNode rowNode = qvariant_cast<VPieceNode>(rowItem->data(Qt::UserRole));
1632  rowNode.setNotchCount(value);
1633  rowItem->setData(Qt::UserRole, QVariant::fromValue(rowNode));
1634 
1635  nodeListChanged();
1636  }
1637  }
1638 }
1639 
1640 //---------------------------------------------------------------------------------------------------------------------
1642 {
1643  QPlainTextEdit *lineEdit[2] = {ui->rotationFormula_LineEdit, ui->lengthFormula_LineEdit};
1644  bool formulasOK[2] = {true, true};
1645 
1646  for (int i = 0; i < 2; ++i)
1647  {
1648  QLabel *labelValue;
1649  QLabel *labelText;
1650  QString labelUnits;
1651  if (i == 0)
1652  {
1653  labelValue = ui->labelRot;
1654  labelText = ui->labelEditRot;
1655  labelUnits = degreeSymbol;
1656  }
1657  else
1658  {
1659  labelValue = ui->labelLen;
1660  labelText = ui->labelEditLen;
1661  labelUnits = QLatin1String(" ") + UnitsToStr(qApp->patternUnit());
1662  }
1663 
1664  labelValue->setToolTip(tr("Value"));
1665 
1666  QString formula = lineEdit[i]->toPlainText().simplified();
1667  QString formulaValueStr;
1668  try
1669  {
1670  formula.replace("\n", " ");
1671  formula = qApp->TrVars()->FormulaFromUser(formula, qApp->Settings()->GetOsSeparator());
1672  Calculator calculation;
1673  qreal calculatedValue = calculation.EvalFormula(data->DataVariables(), formula);
1674  if (qIsInf(calculatedValue) == true || qIsNaN(calculatedValue) == true)
1675  {
1676  throw qmu::QmuParserError(tr("Infinite/undefined result"));
1677  }
1678  else if (i == 1 && calculatedValue <= 0.0)
1679  {
1680  throw qmu::QmuParserError(tr("Length should be positive"));
1681  }
1682  else
1683  {
1684  formulaValueStr.setNum(calculatedValue, 'f', 2);
1685  ChangeColor(labelText, okColor);
1686  }
1687  }
1688  catch (qmu::QmuParserError &e)
1689  {
1690  formulaValueStr = tr("Error");
1691  !flagGrainlineAnchor ? ChangeColor(labelText, Qt::red) : ChangeColor(labelText, okColor);
1692  formulasOK[i] = false;
1693  labelValue->setToolTip(tr("Parser error: %1").arg(e.GetMsg()));
1694  }
1695 
1696  if (formulasOK[i] && formulaValueStr.isEmpty() == false)
1697  {
1698  formulaValueStr += labelUnits;
1699  }
1700  labelValue->setText(formulaValueStr);
1701  }
1702 
1703  flagGrainlineFormula = formulasOK[0] && formulasOK[1];
1705  {
1706  setErrorText(TabOrder::Grainline, tr("Grainline"));
1707  }
1708  else
1709  {
1711  }
1712  CheckState();
1713 }
1714 
1715 //---------------------------------------------------------------------------------------------------------------------
1717 {
1718  QPlainTextEdit *lineEdit[3] = {ui->pieceLabelWidthFormula_LineEdit, ui->pieceLabelHeightFormula_LineEdit,
1719  ui->pieceLabelAngleFormula_LineEdit};
1720  bool formulasOK[3] = {true, true, true};
1721 
1722  for (int i = 0; i < 3; ++i)
1723  {
1724  QLabel *labelValue;
1725  QLabel *labelText;
1726  QString labelUnits;
1727  if (i == 0)
1728  {
1729  labelValue = ui->labelDLWidth;
1730  labelText = ui->labelEditDLWidth;
1731  labelUnits = QLatin1String(" ") + UnitsToStr(qApp->patternUnit());
1732  }
1733  else if (i == 1)
1734  {
1735  labelValue = ui->labelDLHeight;
1736  labelText = ui->labelEditDLHeight;
1737  labelUnits = QLatin1String(" ") + UnitsToStr(qApp->patternUnit());
1738  }
1739  else
1740  {
1741  labelValue = ui->labelDLAngle;
1742  labelText = ui->labelEditDLAngle;
1743  labelUnits = degreeSymbol;
1744  }
1745 
1746  labelValue->setToolTip(tr("Value"));
1747 
1748  QString formula = lineEdit[i]->toPlainText().simplified();
1749  QString formulaValueStr;
1750  try
1751  {
1752  formula.replace("\n", " ");
1753  formula = qApp->TrVars()->FormulaFromUser(formula, qApp->Settings()->GetOsSeparator());
1754  Calculator calculation;
1755  qreal calculatedValue = calculation.EvalFormula(data->DataVariables(), formula);
1756  if (qIsInf(calculatedValue) == true || qIsNaN(calculatedValue) == true)
1757  {
1758  throw qmu::QmuParserError(tr("Infinite/undefined result"));
1759  }
1760  else if ((i == 0 || i == 1) && calculatedValue <= 0.0)
1761  {
1762  throw qmu::QmuParserError(tr("Length should be positive"));
1763  }
1764  else
1765  {
1766  formulaValueStr.setNum(calculatedValue, 'f', 2);
1767  ChangeColor(labelText, okColor);
1768  }
1769  }
1770  catch (qmu::QmuParserError &e)
1771  {
1772  formulaValueStr = tr("Error");
1773  !flagPieceLabelAnchor ? ChangeColor(labelText, Qt::red) : ChangeColor(labelText, okColor);
1774  formulasOK[i] = false;
1775  labelValue->setToolTip(tr("Parser error: %1").arg(e.GetMsg()));
1776  }
1777 
1778  if (formulasOK[i] && formulaValueStr.isEmpty() == false)
1779  {
1780  formulaValueStr += labelUnits;
1781  }
1782  labelValue->setText(formulaValueStr);
1783  }
1784 
1785  flagPieceLabelAngle = formulasOK[2];
1786  flagPieceLabelFormula = formulasOK[0] && formulasOK[1];
1788  {
1789  setErrorText(TabOrder::Labels, tr("Labels"));
1790  QIcon icon(":/icons/win.icon.theme/16x16/status/dialog-warning.png");
1791  ui->labels_TabWidget->setTabIcon(ui->labels_TabWidget->indexOf(ui->pieceLabel_Tab), icon);
1792  }
1793  else
1794  {
1796  }
1797  CheckState();
1798 }
1799 
1800 //---------------------------------------------------------------------------------------------------------------------
1802 {
1803  QPlainTextEdit *lineEdit[3] = {ui->patternLabelWidthFormula_LineEdit, ui->patternLabelHeightFormula_LineEdit,
1804  ui->patternLabelAngleFormula_LineEdit};
1805  bool formulasOK[3] = {true, true, true};
1806 
1807  for (int i = 0; i < 3; ++i)
1808  {
1809  QLabel *labelValue;
1810  QLabel *labelText;
1811  QString labelUnits;
1812  if (i == 0)
1813  {
1814  labelValue = ui->labelPLWidth;
1815  labelText = ui->labelEditPLWidth;
1816  labelUnits = QLatin1String(" ") + UnitsToStr(qApp->patternUnit());
1817  }
1818  else if (i == 1)
1819  {
1820  labelValue = ui->labelPLHeight;
1821  labelText = ui->labelEditPLHeight;
1822  labelUnits = QLatin1String(" ") + UnitsToStr(qApp->patternUnit());
1823  }
1824  else
1825  {
1826  labelValue = ui->labelPLAngle;
1827  labelText = ui->labelEditPLAngle;
1828  labelUnits = degreeSymbol;
1829  }
1830 
1831  labelValue->setToolTip(tr("Value"));
1832 
1833  QString formula = lineEdit[i]->toPlainText().simplified();
1834  QString formulaValueStr;
1835  try
1836  {
1837  formula.replace("\n", " ");
1838  formula = qApp->TrVars()->FormulaFromUser(formula, qApp->Settings()->GetOsSeparator());
1839  Calculator calculation;
1840  qreal calculatedValue = calculation.EvalFormula(data->DataVariables(), formula);
1841  if (qIsInf(calculatedValue) == true || qIsNaN(calculatedValue) == true)
1842  {
1843  throw qmu::QmuParserError(tr("Infinite/undefined result"));
1844  }
1845  else if ((i == 0 || i == 1) && calculatedValue <= 0.0)
1846  {
1847  throw qmu::QmuParserError(tr("Length should be positive"));
1848  }
1849  else
1850  {
1851  formulaValueStr.setNum(calculatedValue, 'f', 2);
1852  ChangeColor(labelText, okColor);
1853  }
1854  }
1855  catch (qmu::QmuParserError &e)
1856  {
1857  formulaValueStr = tr("Error");
1858  !flagPatternLabelAnchor ? ChangeColor(labelText, Qt::red) : ChangeColor(labelText, okColor);
1859  formulasOK[i] = false;
1860  labelValue->setToolTip(tr("Parser error: %1").arg(e.GetMsg()));
1861  }
1862 
1863  if (formulasOK[i] && formulaValueStr.isEmpty() == false)
1864  {
1865  formulaValueStr += labelUnits;
1866  }
1867  labelValue->setText(formulaValueStr);
1868  }
1869 
1870  flagPatternLabelAngle = formulasOK[2];
1871  flagPatternLabelFormula = formulasOK[0] && formulasOK[1];
1873  {
1874  setErrorText(TabOrder::Labels, tr("Labels"));
1875  QIcon icon(":/icons/win.icon.theme/16x16/status/dialog-warning.png");
1876  ui->labels_TabWidget->setTabIcon(ui->labels_TabWidget->indexOf(ui->patternLabel_Tab), icon);
1877  }
1878  else
1879  {
1881  }
1882  CheckState();
1883 }
1884 
1885 //---------------------------------------------------------------------------------------------------------------------
1887 {
1888  if (ui->grainline_GroupBox->isChecked() == true)
1889  {
1892  }
1893  else
1894  {
1895  flagGrainlineFormula = true;
1897  CheckState();
1898  }
1899 }
1900 
1901 //---------------------------------------------------------------------------------------------------------------------
1903 {
1904  if (ui->pieceLabel_GroupBox->isChecked() == true)
1905  {
1908  }
1909  else
1910  {
1911  flagPieceLabelAngle = true;
1912  flagPieceLabelFormula = true;
1914  CheckState();
1915  }
1916 }
1917 
1918 //---------------------------------------------------------------------------------------------------------------------
1920 {
1921  if (ui->patternLabel_GroupBox->isChecked() == true)
1922  {
1925  }
1926  else
1927  {
1928  flagPatternLabelAngle = true;
1929  flagPatternLabelFormula = true;
1931  CheckState();
1932  }
1933 }
1934 
1935 //---------------------------------------------------------------------------------------------------------------------
1937 {
1938  QPlainTextEdit *labelFormula;
1939  bool checkForZero;
1940  QString title;
1941 
1942  if (sender() == ui->length_PushButton)
1943  {
1944  labelFormula = ui->lengthFormula_LineEdit;
1945  checkForZero = true;
1946  title = tr("Edit length");
1947  }
1948  else if (sender() == ui->rotation_PushButton)
1949  {
1950  labelFormula = ui->rotationFormula_LineEdit;
1951  checkForZero = false;
1952  title = tr("Edit angle");
1953  }
1954  else
1955  {
1956  // should not get here!
1957  return;
1958  }
1959 
1960  EditFormulaDialog dialog(data, NULL_ID, this);
1961  dialog.setWindowTitle(title);
1962  dialog.SetFormula(qApp->TrVars()->TryFormulaFromUser(labelFormula->toPlainText(), qApp->Settings()->GetOsSeparator()));
1963  dialog.setCheckZero(checkForZero);
1964  if (dialog.exec() == QDialog::Accepted)
1965  {
1966  QString formula = dialog.GetFormula();
1967  formula.replace("\n", " ");
1968 
1969  if (sender() == ui->length_PushButton)
1970  {
1971  setGrainlineLength(formula);
1972  }
1973  else if (sender() == ui->rotation_PushButton)
1974  {
1975  setGrainlineAngle(formula);
1976  }
1977  else
1978  {
1979  // should not get here!
1980  labelFormula->setPlainText(formula);
1981  }
1983  }
1984 }
1985 
1986 //---------------------------------------------------------------------------------------------------------------------
1988 {
1989  QPlainTextEdit *labelFormula;
1990  bool checkForZero;
1991  QString title;
1992 
1993  if (sender() == ui->pieceLabelHeght_PushButton)
1994  {
1995  labelFormula = ui->pieceLabelHeightFormula_LineEdit;
1996  checkForZero = true;
1997  title = tr("Edit height");
1998  }
1999  else if (sender() == ui->pieceLabelWidth_PushButton)
2000  {
2001  labelFormula = ui->pieceLabelWidthFormula_LineEdit;
2002  checkForZero = true;
2003  title = tr("Edit width");
2004  }
2005  else if (sender() == ui->pieceLabelAngle_PushButton)
2006  {
2007  labelFormula = ui->pieceLabelAngleFormula_LineEdit;
2008  checkForZero = false;
2009  title = tr("Edit angle");
2010  }
2011  else
2012  {
2013  // should not get here!
2014  return;
2015  }
2016 
2017  EditFormulaDialog dialog(data, NULL_ID, this);
2018  dialog.setWindowTitle(title);
2019  dialog.SetFormula(qApp->TrVars()->TryFormulaFromUser(labelFormula->toPlainText(), qApp->Settings()->GetOsSeparator()));
2020  dialog.setCheckZero(checkForZero);
2021  if (dialog.exec() == QDialog::Accepted)
2022  {
2023  QString formula = dialog.GetFormula();
2024  formula.replace("\n", " ");
2025  if (sender() == ui->pieceLabelHeght_PushButton)
2026  {
2027  setPieceLabelHeight(formula);
2028  }
2029  else if (sender() == ui->pieceLabelWidth_PushButton)
2030  {
2031  setPieceLabelWidth(formula);
2032  }
2033  else if (sender() == ui->pieceLabelAngle_PushButton)
2034  {
2035  setPieceLabelAngle(formula);
2036  }
2037  else
2038  {
2039  // should not get here!
2040  labelFormula->setPlainText(formula);
2041  }
2043  }
2044 }
2045 
2046 //---------------------------------------------------------------------------------------------------------------------
2048 {
2049  QPlainTextEdit *labelFormula;
2050  bool checkForZero;
2051  QString title;
2052 
2053  if (sender() == ui->patternLabelHeght_PushButton)
2054  {
2055  labelFormula = ui->patternLabelHeightFormula_LineEdit;
2056  checkForZero = true;
2057  title = tr("Edit height");
2058  }
2059  else if (sender() == ui->patternLabelWidth_PushButton)
2060  {
2061  labelFormula = ui->patternLabelWidthFormula_LineEdit;
2062  checkForZero = true;
2063  title = tr("Edit width");
2064  }
2065  else if (sender() == ui->patternLabelAngle_PushButton)
2066  {
2067  labelFormula = ui->patternLabelAngleFormula_LineEdit;
2068  checkForZero = false;
2069  title = tr("Edit angle");
2070  }
2071  else
2072  {
2073  // should not get here!
2074  return;
2075  }
2076 
2077  EditFormulaDialog dialog(data, NULL_ID, this);
2078  dialog.setWindowTitle(title);
2079  dialog.SetFormula(qApp->TrVars()->TryFormulaFromUser(labelFormula->toPlainText(), qApp->Settings()->GetOsSeparator()));
2080  dialog.setCheckZero(checkForZero);
2081  if (dialog.exec() == QDialog::Accepted)
2082  {
2083  QString formula = dialog.GetFormula();
2084  formula.replace("\n", " ");
2085  if (sender() == ui->patternLabelHeght_PushButton)
2086  {
2087  setPatternLabelHeight(formula);
2088  }
2089  else if (sender() == ui->patternLabelWidth_PushButton)
2090  {
2091  setPatternLabelWidth(formula);
2092  }
2093  else if (sender() == ui->patternLabelAngle_PushButton)
2094  {
2095  setPatternLabelAngle(formula);
2096  }
2097  else
2098  {
2099  // should not get here!
2100  labelFormula->setPlainText(formula);
2101  }
2103  }
2104 }
2105 
2106 //---------------------------------------------------------------------------------------------------------------------
2108 {
2109  DeployFormula(ui->rotationFormula_LineEdit, ui->showRotation_PushButton, m_rotationBaseHeight);
2110 }
2111 
2112 //---------------------------------------------------------------------------------------------------------------------
2114 {
2115  DeployFormula(ui->lengthFormula_LineEdit, ui->showLength_PushButton, m_lengthBaseHeight);
2116 }
2117 
2118 //---------------------------------------------------------------------------------------------------------------------
2120 {
2121  DeployFormula(ui->pieceLabelWidthFormula_LineEdit, ui->showPieceLabelWidth_PushButton,
2123 }
2124 
2125 //---------------------------------------------------------------------------------------------------------------------
2127 {
2128  DeployFormula(ui->pieceLabelHeightFormula_LineEdit, ui->showPieceLabelHeight_PushButton,
2130 }
2131 
2132 //---------------------------------------------------------------------------------------------------------------------
2134 {
2135  DeployFormula(ui->pieceLabelAngleFormula_LineEdit, ui->showPieceLabelAngle_PushButton,
2137 }
2138 
2139 //---------------------------------------------------------------------------------------------------------------------
2141 {
2142  DeployFormula(ui->patternLabelWidthFormula_LineEdit, ui->showPatternLabelWidth_PushButton,
2144 }
2145 
2146 //---------------------------------------------------------------------------------------------------------------------
2148 {
2149  DeployFormula(ui->patternLabelHeightFormula_LineEdit, ui->showPatternLabelHeight_PushButton,
2151 }
2152 
2153 //---------------------------------------------------------------------------------------------------------------------
2155 {
2156  DeployFormula(ui->patternLabelAngleFormula_LineEdit, ui->showPatternLabelAngle_PushButton,
2158 }
2159 
2160 //---------------------------------------------------------------------------------------------------------------------
2162 {
2164  {
2165  clearErrorText(TabOrder::Grainline, tr("Grainline "));
2166  }
2167 }
2168 
2169 //---------------------------------------------------------------------------------------------------------------------
2171 {
2173  {
2174  clearErrorText(TabOrder::Labels, tr("Labels "));
2175  QIcon icon(":/icon/32x32/piece_label.png");
2176  ui->labels_TabWidget->setTabIcon(ui->labels_TabWidget->indexOf(ui->pieceLabel_Tab), icon);
2177  }
2179  {
2180  clearErrorText(TabOrder::Labels, tr("Labels "));
2181  QIcon icon(":/icon/32x32/pattern_label.png");
2182  ui->labels_TabWidget->setTabIcon(ui->labels_TabWidget->indexOf(ui->patternLabel_Tab), icon);
2183  }
2184 }
2185 
2186 //---------------------------------------------------------------------------------------------------------------------
2188 {
2189  labelEditFormula = ui->widthEdit_Label;
2190  const QString postfix = UnitsToStr(qApp->patternUnit(), true);
2191  const QString formula = ui->widthFormula_PlainTextEdit->toPlainText();
2192  m_saWidth = Eval(formula, flagFormula, ui->widthResult_Label, postfix, false, true);
2193 
2194  if (m_saWidth >= 0)
2195  {
2196  VContainer *locData = const_cast<VContainer *> (data);
2198  QString().setNum(m_saWidth), true,
2199  tr("Current seam allowance")));
2200 
2203  }
2204 }
2205 
2206 //---------------------------------------------------------------------------------------------------------------------
2208 {
2209  if (ui->nodes_ComboBox->count() > 0)
2210  {
2211  labelEditFormula = ui->beforeWidthEdit_Label;
2212  const QString postfix = UnitsToStr(qApp->patternUnit(), true);
2213  const QString formula = ui->beforeWidthFormula_PlainTextEdit->toPlainText();
2214  Eval(formula, flagBeforeFormula, ui->beforeWidthResult_Label, postfix, false, true);
2215 
2216  const QString formulaSABefore = getFormulaFromUser(ui->beforeWidthFormula_PlainTextEdit);
2217  updateNodeBeforeSeamAllowance(formulaSABefore);
2218  enableDefaultButton(ui->beforeDefault_PushButton, formulaSABefore);
2219  }
2220 }
2221 
2222 //---------------------------------------------------------------------------------------------------------------------
2224 {
2225  if (ui->nodes_ComboBox->count() > 0)
2226  {
2227  labelEditFormula = ui->afterWidthEdit_Label;
2228  const QString postfix = UnitsToStr(qApp->patternUnit(), true);
2229  const QString formula = ui->afterWidthFormula_PlainTextEdit->toPlainText();
2230  Eval(formula, flagAfterFormula, ui->afterWidthResult_Label, postfix, false, true);
2231 
2232  const QString formulaSAAfter = getFormulaFromUser(ui->afterWidthFormula_PlainTextEdit);
2233  updateNodeAfterSeamAllowance(formulaSAAfter);
2234  enableDefaultButton(ui->afterDefault_PushButton, formulaSAAfter);
2235  }
2236 }
2237 
2238 //---------------------------------------------------------------------------------------------------------------------
2240 {
2241  EditFormulaDialog *dialog = new EditFormulaDialog(data, toolId, this);
2242  dialog->setWindowTitle(tr("Edit seam allowance width"));
2244  dialog->setCheckLessThanZero(true);
2245  dialog->setPostfix(UnitsToStr(qApp->patternUnit(), true));
2246  if (dialog->exec() == QDialog::Accepted)
2247  {
2249  }
2250  delete dialog;
2251 }
2252 
2253 //---------------------------------------------------------------------------------------------------------------------
2255 {
2256  EditFormulaDialog *dialog = new EditFormulaDialog(data, toolId, this);
2257  dialog->setWindowTitle(tr("Edit seam allowance width before"));
2258  dialog->SetFormula(getFormulaFromUser(ui->beforeWidthFormula_PlainTextEdit));
2259  dialog->setCheckLessThanZero(true);
2260  dialog->setPostfix(UnitsToStr(qApp->patternUnit(), true));
2261  if (dialog->exec() == QDialog::Accepted)
2262  {
2264  }
2265  delete dialog;
2266 }
2267 
2268 //---------------------------------------------------------------------------------------------------------------------
2270 {
2271  EditFormulaDialog *dialog = new EditFormulaDialog(data, toolId, this);
2272  dialog->setWindowTitle(tr("Edit seam allowance width after"));
2273  dialog->SetFormula(getFormulaFromUser(ui->afterWidthFormula_PlainTextEdit));
2274  dialog->setCheckLessThanZero(true);
2275  dialog->setPostfix(UnitsToStr(qApp->patternUnit(), true));
2276  if (dialog->exec() == QDialog::Accepted)
2277  {
2279  }
2280  delete dialog;
2281 }
2282 
2283 //---------------------------------------------------------------------------------------------------------------------
2285 {
2286  labelEditFormula = ui->widthEdit_Label;
2287  labelResultCalculation = ui->widthResult_Label;
2288  const QString postfix = UnitsToStr(qApp->patternUnit(), true);
2289  ValFormulaChanged(flagFormula, ui->widthFormula_PlainTextEdit, m_timerWidth, postfix);
2290 }
2291 
2292 //---------------------------------------------------------------------------------------------------------------------
2294 {
2295  labelEditFormula = ui->beforeWidthEdit_Label;
2296  labelResultCalculation = ui->beforeWidthResult_Label;
2297  const QString postfix = UnitsToStr(qApp->patternUnit(), true);
2298 
2299  ValFormulaChanged(flagBeforeFormula, ui->beforeWidthFormula_PlainTextEdit, m_timerWidthBefore, postfix);
2300 }
2301 
2302 //---------------------------------------------------------------------------------------------------------------------
2304 {
2305  labelEditFormula = ui->afterWidthEdit_Label;
2306  labelResultCalculation = ui->afterWidthResult_Label;
2307  const QString postfix = UnitsToStr(qApp->patternUnit(), true);
2308 
2309  ValFormulaChanged(flagAfterFormula, ui->afterWidthFormula_PlainTextEdit, m_timerWidthAfter, postfix);
2310 }
2311 
2312 //---------------------------------------------------------------------------------------------------------------------
2314 {
2315  DeployFormula(ui->widthFormula_PlainTextEdit, ui->widthGrow_PushButton, m_widthFormula);
2316 }
2317 
2318 //---------------------------------------------------------------------------------------------------------------------
2320 {
2321  DeployFormula(ui->beforeWidthFormula_PlainTextEdit, ui->beforeWidthGrow_PushButton,
2323 }
2324 
2325 //---------------------------------------------------------------------------------------------------------------------
2327 {
2328  DeployFormula(ui->afterWidthFormula_PlainTextEdit, ui->afterWidthGrow_PushButton,
2330 }
2331 
2332 //---------------------------------------------------------------------------------------------------------------------
2334 {
2335  QColor color = okColor;
2336  const quint32 topAnchorId = getCurrentObjectId(ui->grainlineTopAnchor_ComboBox);
2337  const quint32 bottomAnchorId = getCurrentObjectId(ui->grainlineBottomAnchor_ComboBox);
2338  if (topAnchorId != NULL_ID && bottomAnchorId != NULL_ID && topAnchorId != bottomAnchorId)
2339  {
2340  flagGrainlineAnchor = true;
2341  color = okColor;
2342 
2344  }
2345  else
2346  {
2347  flagGrainlineAnchor = false;
2348  topAnchorId == NULL_ID && bottomAnchorId == NULL_ID ? color = okColor : color = errorColor;
2349 
2351  {
2352  ui->menuTab_ListWidget->item(TabOrder::Grainline)->setText(QString(tr("Grainline")));
2353  }
2354  }
2356  ChangeColor(ui->topGrainlineAnchor_Label, color);
2357  ChangeColor(ui->bottomGrainlineAnchor_Label, color);
2358  CheckState();
2359 }
2360 
2361 //---------------------------------------------------------------------------------------------------------------------
2363 {
2364  QColor color = okColor;
2365  const quint32 topAnchorId = getCurrentObjectId(ui->pieceLabelTopLeftAnchor_ComboBox);
2366  const quint32 bottomAnchorId = getCurrentObjectId(ui->pieceLabelBottomRightAnchor_ComboBox);
2367  if (topAnchorId != NULL_ID && bottomAnchorId != NULL_ID && topAnchorId != bottomAnchorId)
2368  {
2369  flagPieceLabelAnchor = true;
2370  color = okColor;
2371 
2373  {
2374  clearErrorText(TabOrder::Labels, tr("Labels "));
2375  QIcon icon(":/icon/32x32/piece_label.png");
2376  ui->labels_TabWidget->setTabIcon(ui->labels_TabWidget->indexOf(ui->pieceLabel_Tab), icon);
2377  }
2378  }
2379  else
2380  {
2381  flagPieceLabelAnchor = false;
2382  topAnchorId == NULL_ID && bottomAnchorId == NULL_ID ? color = okColor : color = errorColor;
2383 
2384  setErrorText(TabOrder::Labels, tr("Labels"));
2385  QIcon icon(":/icons/win.icon.theme/16x16/status/dialog-warning.png");
2386  ui->labels_TabWidget->setTabIcon(ui->labels_TabWidget->indexOf(ui->pieceLabel_Tab), icon);
2387  }
2389  ChangeColor(ui->labelDLTopLeftAnchor, color);
2390  ChangeColor(ui->labelDLBottomRightAnchor, color);
2391  CheckState();
2392 }
2393 
2394 //---------------------------------------------------------------------------------------------------------------------
2396 {
2397  QColor color = okColor;
2398  const quint32 topAnchorId = getCurrentObjectId(ui->patternLabelTopLeftAnchor_ComboBox);
2399  const quint32 bottomAnchorId = getCurrentObjectId(ui->patternLabelBottomRightAnchor_ComboBox);
2400  if (topAnchorId != NULL_ID && bottomAnchorId != NULL_ID && topAnchorId != bottomAnchorId)
2401  {
2402  flagPatternLabelAnchor = true;
2403  color = okColor;
2404 
2406  {
2407  clearErrorText(TabOrder::Labels, tr("Labels "));
2408  QIcon icon(":/icon/32x32/pattern_label.png");
2409  ui->labels_TabWidget->setTabIcon(ui->labels_TabWidget->indexOf(ui->patternLabel_Tab), icon);
2410  }
2411  }
2412  else
2413  {
2414  flagPatternLabelAnchor = false;
2415  topAnchorId == NULL_ID && bottomAnchorId == NULL_ID ? color = okColor : color = errorColor;
2416 
2417  setErrorText(TabOrder::Labels, tr("Labels"));
2418  QIcon icon(":/icons/win.icon.theme/16x16/status/dialog-warning.png");
2419  ui->labels_TabWidget->setTabIcon(ui->labels_TabWidget->indexOf(ui->patternLabel_Tab), icon);
2420  }
2422  ChangeColor(ui->labelPLTopLeftAnchor, color);
2423  ChangeColor(ui->labelPLBottomRightAnchor, color);
2424  CheckState();
2425 }
2426 
2427 //---------------------------------------------------------------------------------------------------------------------
2429 {
2430  QVector<VLabelTemplateLine> patternLabelLines = qApp->getCurrentDocument()->getPatternLabelTemplate();
2431  EditLabelTemplateDialog editor(qApp->getCurrentDocument());
2432  editor.SetTemplate(patternLabelLines);
2433  editor.SetPiece(GetPiece());
2434 
2435  if (QDialog::Accepted == editor.exec())
2436  {
2437  patternLabelLines = editor.GetTemplate();
2438  qApp->getCurrentDocument()->setPatternLabelTemplate(patternLabelLines);
2439  emit qApp->getCurrentDocument()->UpdatePatternLabel();
2440  }
2441 }
2442 
2443 //---------------------------------------------------------------------------------------------------------------------
2445 {
2446  EditLabelTemplateDialog editor(qApp->getCurrentDocument());
2448  editor.SetPiece(GetPiece());
2449 
2450  if (QDialog::Accepted == editor.exec())
2451  {
2452  m_pieceLabelLines = editor.GetTemplate();
2453  }
2454 }
2455 
2456 //---------------------------------------------------------------------------------------------------------------------
2458 {
2459  VPiece piece;
2460  piece.GetPath().SetNodes(GetListInternals<VPieceNode>(ui->mainPath_ListWidget));
2461  piece.SetCustomSARecords(GetListInternals<CustomSARecord>(ui->customSeamAllowance_ListWidget));
2462  piece.SetInternalPaths(GetListInternals<quint32>(ui->internalPaths_ListWidget));
2463  piece.setAnchors(GetListInternals<quint32>(ui->anchorPoints_ListWidget));
2464  piece.SetForbidFlipping(ui->forbidFlipping_CheckBox->isChecked());
2465  piece.SetSeamAllowance(ui->seams_CheckBox->isChecked());
2466  piece.SetSeamAllowanceBuiltIn(ui->builtIn_CheckBox->isChecked());
2467  piece.setHideSeamLine(ui->hideSeamLine_CheckBox->isChecked());
2468  piece.SetName(ui->pieceName_LineEdit->text());
2469  piece.setColor(getPieceColor());
2470  piece.setFill(getPieceFill());
2471  piece.SetInLayout(isInLayout());
2472  piece.setIsLocked(getPieceLock());
2473  piece.SetMx(m_mx);
2474  piece.SetMy(m_my);
2475  piece.setSeamAllowanceWidthFormula(getFormulaFromUser(ui->widthFormula_PlainTextEdit), m_saWidth);
2476 
2477  piece.GetPatternPieceData() = m_oldData;
2478  piece.GetPatternPieceData().SetLetter(ui->letter_LineEdit->text());
2479  piece.GetPatternPieceData().SetAnnotation(ui->annotation_LineEdit->text());
2480  piece.GetPatternPieceData().SetOrientation(ui->orientation_ComboBox->currentText());
2481  piece.GetPatternPieceData().SetRotationWay(ui->rotation_ComboBox->currentText());
2482  piece.GetPatternPieceData().SetTilt(ui->tilt_ComboBox->currentText());
2483  piece.GetPatternPieceData().SetFoldPosition(ui->foldPosition_ComboBox->currentText());
2484  piece.GetPatternPieceData().SetQuantity(ui->quantity_SpinBox->value());
2485  piece.GetPatternPieceData().SetOnFold(ui->fold_CheckBox->isChecked());
2487  piece.GetPatternPieceData().SetVisible(ui->pieceLabel_GroupBox->isChecked());
2488  piece.GetPatternPieceData().SetLabelWidth(getFormulaFromUser(ui->pieceLabelWidthFormula_LineEdit));
2489  piece.GetPatternPieceData().SetLabelHeight(getFormulaFromUser(ui->pieceLabelHeightFormula_LineEdit));
2490  piece.GetPatternPieceData().SetRotation(getFormulaFromUser(ui->pieceLabelAngleFormula_LineEdit));
2492  piece.GetPatternPieceData().setCenterAnchorPoint(getCurrentObjectId(ui->pieceLabelCenterAnchor_ComboBox));
2493  piece.GetPatternPieceData().setTopLeftAnchorPoint(getCurrentObjectId(ui->pieceLabelTopLeftAnchor_ComboBox));
2494  piece.GetPatternPieceData().setBottomRightAnchorPoint(getCurrentObjectId(ui->pieceLabelBottomRightAnchor_ComboBox));
2495 
2496  piece.GetPatternInfo() = m_oldGeom;
2497  piece.GetPatternInfo().SetVisible(ui->patternLabel_GroupBox->isChecked());
2498  piece.GetPatternInfo().SetLabelWidth(getFormulaFromUser(ui->patternLabelWidthFormula_LineEdit));
2499  piece.GetPatternInfo().SetLabelHeight(getFormulaFromUser(ui->patternLabelHeightFormula_LineEdit));
2500  piece.GetPatternInfo().SetRotation(getFormulaFromUser(ui->patternLabelAngleFormula_LineEdit));
2501  piece.GetPatternInfo().setCenterAnchorPoint(getCurrentObjectId(ui->patternLabelCenterAnchor_ComboBox));
2502  piece.GetPatternInfo().setTopLeftAnchorPoint(getCurrentObjectId(ui->patternLabelTopLeftAnchor_ComboBox));
2503  piece.GetPatternInfo().setBottomRightAnchorPoint(getCurrentObjectId(ui->patternLabelBottomRightAnchor_ComboBox));
2504 
2506  piece.GetGrainlineGeometry().SetVisible(ui->grainline_GroupBox->isChecked());
2507  piece.GetGrainlineGeometry().SetRotation(getFormulaFromUser(ui->rotationFormula_LineEdit));
2508  piece.GetGrainlineGeometry().SetLength(getFormulaFromUser(ui->lengthFormula_LineEdit));
2509  piece.GetGrainlineGeometry().SetArrowType(static_cast<ArrowType>(ui->arrow_ComboBox->currentIndex()));
2510  piece.GetGrainlineGeometry().setCenterAnchorPoint(getCurrentObjectId(ui->grainlineCenterAnchor_ComboBox));
2511  piece.GetGrainlineGeometry().setTopAnchorPoint(getCurrentObjectId(ui->grainlineTopAnchor_ComboBox));
2512  piece.GetGrainlineGeometry().setBottomAnchorPoint(getCurrentObjectId(ui->grainlineBottomAnchor_ComboBox));
2513 
2514  if (applyAllowed == false)
2515  {
2516  VPiecePath path = piece.GetPath();
2517  const QRectF rect = QPolygonF(path.PathPoints(data)).boundingRect();
2518 
2519  qreal width = getFormulaValue(ui->pieceLabelWidthFormula_LineEdit);
2520  qreal height = getFormulaValue(ui->pieceLabelHeightFormula_LineEdit);
2521  qreal xPos = rect.center().x() + (rect.width()/2.0 - width)/2.0;
2522  qreal yPos = rect.center().y() - height/2.0;
2523  piece.GetPatternPieceData().SetPos(QPointF(xPos, yPos));
2524 
2525  xPos = rect.left() + (rect.width()/2.0 - width)/2.0;
2526  yPos = rect.center().y() - height/2.0;
2527  piece.GetPatternInfo().SetPos(QPointF(xPos, yPos));
2528 
2529  xPos = rect.center().x();
2530  yPos = rect.center().y() + getFormulaValue(ui->lengthFormula_LineEdit)/2.0;
2531 
2532  piece.GetGrainlineGeometry().SetPos(QPointF(xPos, yPos));
2533  }
2534  return piece;
2535 }
2536 
2537 //---------------------------------------------------------------------------------------------------------------------
2539 {
2540  newNodeItem(ui->mainPath_ListWidget, node);
2541 }
2542 
2543 //---------------------------------------------------------------------------------------------------------------------
2545 {
2546  if (record.path > NULL_ID)
2547  {
2548  const QString name = getPathName(record.path, record.reverse);
2549 
2550  QListWidgetItem *item = new QListWidgetItem(name);
2551  item->setData(Qt::UserRole, QVariant::fromValue(record));
2552  ui->customSeamAllowance_ListWidget->addItem(item);
2553  ui->customSeamAllowance_ListWidget->setCurrentRow(ui->customSeamAllowance_ListWidget->count()-1);
2554  }
2555 }
2556 
2557 //---------------------------------------------------------------------------------------------------------------------
2559 {
2560  if (path > NULL_ID)
2561  {
2562  const QString name = getPathName(path);
2563 
2564  QListWidgetItem *item = new QListWidgetItem(name);
2565  item->setData(Qt::UserRole, QVariant::fromValue(path));
2566  ui->internalPaths_ListWidget->addItem(item);
2567  ui->internalPaths_ListWidget->setCurrentRow(ui->internalPaths_ListWidget->count()-1);
2568  }
2569 }
2570 
2571 //---------------------------------------------------------------------------------------------------------------------
2572 void PatternPieceDialog::newAnchorPoint(quint32 anchorPoint)
2573 {
2574  if (anchorPoint > NULL_ID)
2575  {
2576  const QSharedPointer<VGObject> anchor = data->GetGObject(anchorPoint);
2577 
2578  QListWidgetItem *item = new QListWidgetItem(anchor->name());
2579  item->setData(Qt::UserRole, QVariant::fromValue(anchorPoint));
2580  ui->anchorPoints_ListWidget->addItem(item);
2581  ui->anchorPoints_ListWidget->setCurrentRow(ui->anchorPoints_ListWidget->count()-1);
2582  }
2583 }
2584 
2585 //---------------------------------------------------------------------------------------------------------------------
2586 QString PatternPieceDialog::getPathName(quint32 path, bool reverse) const
2587 {
2588  QString name;
2589 
2590  if (path > NULL_ID)
2591  {
2592  name = data->GetPiecePath(path).GetName();
2593 
2594  if (reverse)
2595  {
2596  name = QLatin1String("- ") + name;
2597  }
2598  }
2599 
2600  return name;
2601 }
2602 
2603 //---------------------------------------------------------------------------------------------------------------------
2605 {
2606  QString color = ui->color_Label->text();
2607  return color;
2608 }
2609 
2610 //---------------------------------------------------------------------------------------------------------------------
2611 void PatternPieceDialog::setPieceColor(const QString &color)
2612 {
2613  ui->color_Label->setText(color);
2614  ui->color_Label->setPalette(QPalette(color));
2615 }
2616 
2617 //---------------------------------------------------------------------------------------------------------------------
2619 {
2620  QString value = GetComboBoxCurrentData(ui->fill_ComboBox, FillNone);
2621  return value;
2622 }
2623 
2624 //---------------------------------------------------------------------------------------------------------------------
2625 void PatternPieceDialog::setPieceFill(const QString &value)
2626 {
2627  ChangeCurrentData(ui->fill_ComboBox, value);
2628 }
2629 
2630 //---------------------------------------------------------------------------------------------------------------------
2632 {
2633  return m_inLayout;
2634 }
2635 
2636 //---------------------------------------------------------------------------------------------------------------------
2637 void PatternPieceDialog::setInLayout(const bool &state)
2638 {
2639  m_inLayout = state;
2640 }
2641 
2642 //---------------------------------------------------------------------------------------------------------------------
2644 {
2645  return m_isLocked;
2646 }
2647 
2648 //---------------------------------------------------------------------------------------------------------------------
2649 void PatternPieceDialog::setPieceLock(const bool &state)
2650 {
2651  m_isLocked = state;
2652 }
2653 
2654 //---------------------------------------------------------------------------------------------------------------------
2656 {
2657  QString warning = DialogWarningIcon();
2658 
2659  if(CreatePiece().MainPathPoints(data).count() < 3)
2660  {
2661  warning += tr("You need more points!");
2662  ui->status_Label->setText(warning);
2663  return false;
2664  }
2665  else
2666  {
2667  if(!isMainPathClockwise())
2668  {
2669  warning += tr("You must choose points in a clockwise direction!");
2670  ui->status_Label->setText(warning);
2671  return false;
2672  }
2673  if (isFirstPointSameAsLast(ui->mainPath_ListWidget))
2674  {
2675  warning += tr("First point cannot be same as last point!");
2676  ui->status_Label->setText(warning);
2677  return false;
2678  }
2679  else if (doublePointsExist(ui->mainPath_ListWidget))
2680  {
2681  warning += tr("You have double points!");
2682  ui->status_Label->setText(warning);
2683  return false;
2684  }
2685  else if (!isEachPointNameUnique(ui->mainPath_ListWidget))
2686  {
2687  warning += tr("Each point in the path must be unique!");
2688  ui->status_Label->setText(warning);
2689  return false;
2690  }
2691  }
2692 
2693  return true;
2694 }
2695 
2696 //---------------------------------------------------------------------------------------------------------------------
2698 {
2699  flagMainPath = value;
2700  CheckState();
2701 }
2702 
2703 //---------------------------------------------------------------------------------------------------------------------
2705 {
2706  const QVector<QPointF> points = CreatePiece().MainPathPoints(data);
2707  return VPiece::isClockwise(points);
2708 }
2709 
2710 //---------------------------------------------------------------------------------------------------------------------
2712 {
2713  const quint32 id = ui->nodes_ComboBox->currentData().toUInt();
2714 
2715  ui->nodes_GroupBox->setEnabled(true);
2716  ui->nodes_ComboBox->blockSignals(true);
2717  ui->nodes_ComboBox->clear();
2718 
2719  const QVector<VPieceNode> nodes = GetListInternals<VPieceNode>(ui->mainPath_ListWidget);
2720 
2721  for (int i = 0; i < nodes.size(); ++i)
2722  {
2723  const VPieceNode node = nodes.at(i);
2724  if (node.GetTypeTool() == Tool::NodePoint && !node.isExcluded())
2725  {
2726  const NodeInfo info = getNodeInfo(node);
2727 
2728  ui->nodes_ComboBox->addItem(info.name, node.GetId());
2729  }
2730  }
2731 
2732  if (pointNodesExist())
2733  {
2734  const int index = ui->nodes_ComboBox->findData(id);
2735  if (index != -1)
2736  {
2737  ui->nodes_ComboBox->setCurrentIndex(index);
2738  nodeChanged(index);// Need in case combobox index was not changed
2739  }
2740  else
2741  {
2742  ui->nodes_ComboBox->count() > 0 ? nodeChanged(0) : nodeChanged(-1);
2743  }
2744  ui->nodes_ComboBox->blockSignals(false);
2745  }
2746  else
2747  {
2748  ui->nodes_GroupBox->setEnabled(false);
2749  }
2750 }
2751 
2752 //---------------------------------------------------------------------------------------------------------------------
2754 {
2755  const quint32 id = ui->notches_ComboBox->currentData().toUInt();
2756 
2757  ui->notches_ComboBox->blockSignals(true);
2758  ui->notches_ComboBox->clear();
2759 
2760  const QVector<VPieceNode> nodes = GetListInternals<VPieceNode>(ui->mainPath_ListWidget);
2761 
2762  for (int i = 0; i < nodes.size(); ++i)
2763  {
2764  const VPieceNode node = nodes.at(i);
2765  if (node.GetTypeTool() == Tool::NodePoint && node.isNotch())
2766  {
2767  const NodeInfo info = getNodeInfo(node);
2768 
2769  ui->notches_ComboBox->addItem(QIcon(info.icon), info.name, node.GetId());
2770  }
2771  }
2772  ui->notches_ComboBox->blockSignals(false);
2773 
2774  const int index = ui->notches_ComboBox->findData(id);
2775  if (index != -1)
2776  {
2777  ui->notches_ComboBox->setCurrentIndex(index);
2778  notchChanged(index);// Need in case combox index was not changed
2779  }
2780  else
2781  {
2782  ui->notches_ComboBox->count() > 0 ? notchChanged(0) : notchChanged(-1);
2783  }
2784 }
2785 
2786 //---------------------------------------------------------------------------------------------------------------------
2787 QListWidgetItem *PatternPieceDialog::getItemById(quint32 id)
2788 {
2789  for (qint32 i = 0; i < ui->mainPath_ListWidget->count(); ++i)
2790  {
2791  QListWidgetItem *item = ui->mainPath_ListWidget->item(i);
2792  const VPieceNode node = qvariant_cast<VPieceNode>(item->data(Qt::UserRole));
2793 
2794  if (node.GetId() == id)
2795  {
2796  return item;
2797  }
2798  }
2799  return nullptr;
2800 }
2801 
2802 //---------------------------------------------------------------------------------------------------------------------
2804 {
2805  const int count = ui->mainPath_ListWidget->count();
2806  if (count > 0)
2807  {
2808  QListWidgetItem *item = ui->mainPath_ListWidget->item(count-1);
2809  const VPieceNode node = qvariant_cast<VPieceNode>(item->data(Qt::UserRole));
2810  return node.GetId();
2811  }
2812  else
2813  {
2814  return NULL_ID;
2815  }
2816 }
2817 
2818 //---------------------------------------------------------------------------------------------------------------------
2820 {
2821  const int count = ui->mainPath_ListWidget->count();
2822  if (count > 0)
2823  {
2824  QListWidgetItem *item = ui->mainPath_ListWidget->item(count-1);
2825  const VPieceNode node = qvariant_cast<VPieceNode>(item->data(Qt::UserRole));
2826  return node;
2827  }
2828  else
2829  {
2830  return VPieceNode();
2831  }
2832 }
2833 
2834 //---------------------------------------------------------------------------------------------------------------------
2836 {
2837  const QVector<VPieceNode> nodes = GetListInternals<VPieceNode>(ui->mainPath_ListWidget);
2838  for (int i = 0; i < nodes.size(); ++i)
2839  {
2840  const VPieceNode node = nodes.at(i);
2841  if (node.GetTypeTool() == Tool::NodePoint && !node.isExcluded())
2842  {
2843  qDebug() << "point nodes exist";
2844  return true;
2845  }
2846  }
2847  qDebug() << "point nodes do not exist";
2848  return false;
2849 }
2850 
2851 //---------------------------------------------------------------------------------------------------------------------
2853 {
2855  nodeListChanged();
2856 }
2857 
2858 //---------------------------------------------------------------------------------------------------------------------
2860 {
2862  nodeListChanged();
2863 }
2864 
2865 //---------------------------------------------------------------------------------------------------------------------
2867 {
2868  const int index = ui->nodes_ComboBox->currentIndex();
2869  if (index != -1)
2870  {
2871  QListWidgetItem *rowItem = getItemById(ui->nodes_ComboBox->currentData().toUInt());
2872  if (rowItem)
2873  {
2874  VPieceNode rowNode = qvariant_cast<VPieceNode>(rowItem->data(Qt::UserRole));
2875  rowNode.setBeforeSAFormula(formula);
2876  rowItem->setData(Qt::UserRole, QVariant::fromValue(rowNode));
2877  }
2878  }
2879 }
2880 
2881 //---------------------------------------------------------------------------------------------------------------------
2883 {
2884  const int index = ui->nodes_ComboBox->currentIndex();
2885  if (index != -1)
2886  {
2887  QListWidgetItem *rowItem = getItemById(ui->nodes_ComboBox->currentData().toUInt());
2888  if (rowItem)
2889  {
2890  VPieceNode rowNode = qvariant_cast<VPieceNode>(rowItem->data(Qt::UserRole));
2891  rowNode.setAfterSAFormula(formula);
2892  rowItem->setData(Qt::UserRole, QVariant::fromValue(rowNode));
2893  }
2894  }
2895 }
2896 
2897 //---------------------------------------------------------------------------------------------------------------------
2899 {
2900  ui->forbidFlipping_CheckBox->setChecked(qApp->Settings()->getForbidPieceFlipping());
2901  ui->hideSeamLine_CheckBox->setChecked(qApp->Settings()->isHideSeamLine());
2902 
2903  ui->mainPath_ListWidget->installEventFilter(this);
2904  ui->mainPath_ListWidget->setContextMenuPolicy(Qt::CustomContextMenu);
2905  connect(ui->mainPath_ListWidget, &QListWidget::customContextMenuRequested, this,
2907 
2908  connect(ui->mainPath_ListWidget->model(), &QAbstractItemModel::rowsMoved, this, [this]()
2909  {
2910  nodeListChanged();
2911  validateObjects(isMainPathValid());
2912  });
2913 
2914  connect(ui->mainPath_ListWidget, &QListWidget::itemSelectionChanged,
2916  connect(ui->moveTop_ToolButton,&QToolButton::clicked, this, [this]()
2917  {
2918  moveListRowTop(ui->mainPath_ListWidget);
2919  validateObjects(isMainPathValid());
2920  });
2921  connect(ui->moveUp_ToolButton, &QToolButton::clicked, this, [this]()
2922  {
2923  moveListRowUp(ui->mainPath_ListWidget);
2924  validateObjects(isMainPathValid());
2925  });
2926  connect(ui->moveDown_ToolButton, &QToolButton::clicked, this, [this]()
2927  {
2928  moveListRowDown(ui->mainPath_ListWidget);
2929  validateObjects(isMainPathValid());
2930  });
2931  connect(ui->moveBottom_ToolButton, &QToolButton::clicked, this, [this]()
2932  {
2933  moveListRowBottom(ui->mainPath_ListWidget);
2934  validateObjects(isMainPathValid());
2935  });
2936 }
2937 
2938 //---------------------------------------------------------------------------------------------------------------------
2940 {
2941  ui->seams_CheckBox->setChecked(qApp->Settings()->getDefaultSeamAllowanceVisibilty());
2942 
2943  plainTextEditFormula = ui->widthFormula_PlainTextEdit;
2944  this->m_widthFormula = ui->widthFormula_PlainTextEdit->height();
2945  this->m_beforeWidthFormula = ui->beforeWidthFormula_PlainTextEdit->height();
2946  this->m_afterWidthFormula = ui->afterWidthFormula_PlainTextEdit->height();
2947 
2948  ui->widthFormula_PlainTextEdit->installEventFilter(this);
2949  ui->beforeWidthFormula_PlainTextEdit->installEventFilter(this);
2950  ui->afterWidthFormula_PlainTextEdit->installEventFilter(this);
2951 
2952  m_timerWidth = new QTimer(this);
2953  connect(m_timerWidth, &QTimer::timeout, this, &PatternPieceDialog::evaluateDefaultWidth);
2954 
2955  m_timerWidthBefore = new QTimer(this);
2956  connect(m_timerWidthBefore, &QTimer::timeout, this, &PatternPieceDialog::evaluateBeforeWidth);
2957 
2958  m_timerWidthAfter = new QTimer(this);
2959  connect(m_timerWidthAfter, &QTimer::timeout, this, &PatternPieceDialog::evaluateAfterWidth);
2960 
2961  connect(ui->seams_CheckBox, &QCheckBox::toggled, this, &PatternPieceDialog::enableSeamAllowance);
2962  connect(ui->builtIn_CheckBox, &QCheckBox::toggled, this, &PatternPieceDialog::enableBuiltIn);
2963 
2964  // Initialize the default seam allowance, convert the value if app unit is different than pattern unit
2965  m_saWidth = UnitConvertor(qApp->Settings()->GetDefaultSeamAllowance(),
2966  StrToUnits(qApp->Settings()->GetUnit()), qApp->patternUnit());
2967 
2968  ui->widthFormula_PlainTextEdit->setPlainText(qApp->LocaleToString(m_saWidth));
2969 
2971  connect(ui->nodes_ComboBox, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this,
2973 
2974  connect(ui->beforeDefault_PushButton, &QPushButton::clicked, this, &PatternPieceDialog::enableDefaultBeforeButton);
2975  connect(ui->afterDefault_PushButton, &QPushButton::clicked, this, &PatternPieceDialog::enableDefaultAfterButton);
2976 
2977  initializeNodeAngles(ui->angle_ComboBox);
2978  connect(ui->angle_ComboBox, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this,
2980 
2981  ui->customSeamAllowance_ListWidget->setContextMenuPolicy(Qt::CustomContextMenu);
2982  connect(ui->customSeamAllowance_ListWidget, &QListWidget::customContextMenuRequested, this,
2984  connect(ui->customSeamAllowance_ListWidget, &QListWidget::currentRowChanged, this,
2986  connect(ui->startPoint_ComboBox, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
2988  connect(ui->endPoint_ComboBox, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this,
2990  connect(ui->comboBoxIncludeType, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
2992 
2993  connect(ui->toolButtonExprWidth, &QPushButton::clicked, this, &PatternPieceDialog::editDefaultSeamAllowanceWidth);
2994  connect(ui->beforeExpr_ToolButton, &QPushButton::clicked, this, &PatternPieceDialog::editBeforeSeamAllowanceWidth);
2995  connect(ui->afterExpr_ToolButton, &QPushButton::clicked, this, &PatternPieceDialog::editAfterSeamAllowanceWidth);
2996 
2997  connect(ui->widthFormula_PlainTextEdit, &QPlainTextEdit::textChanged, this,
2999  connect(ui->beforeWidthFormula_PlainTextEdit, &QPlainTextEdit::textChanged, this,
3001  connect(ui->afterWidthFormula_PlainTextEdit, &QPlainTextEdit::textChanged, this,
3003 
3004  connect(ui->widthGrow_PushButton, &QPushButton::clicked, this,
3006  connect(ui->beforeWidthGrow_PushButton, &QPushButton::clicked,
3008  connect(ui->afterWidthGrow_PushButton, &QPushButton::clicked, this,
3010 }
3011 
3012 //---------------------------------------------------------------------------------------------------------------------
3014 {
3015  SCASSERT(box != nullptr);
3016  box->clear();
3017  box->addItem(tr("Empty"), NULL_ID);
3018 
3019  const QVector<VPieceNode> nodes = GetListInternals<VPieceNode>(ui->mainPath_ListWidget);
3020 
3021  for (int i = 0; i < nodes.size(); ++i)
3022  {
3023  const VPieceNode &node = nodes.at(i);
3024  if (node.GetTypeTool() == Tool::NodePoint && !node.isExcluded())
3025  {
3026  const NodeInfo info = getNodeInfo(node);
3027  box->addItem(info.name, node.GetId());
3028  }
3029  }
3030 }
3031 
3032 //---------------------------------------------------------------------------------------------------------------------
3034 {
3035  SCASSERT(box != nullptr);
3036 
3037  quint32 currentId = NULL_ID;
3038  if (box->count() > 0)
3039  {
3040  currentId = box->currentData().toUInt();
3041  }
3042 
3043  box->clear();
3044  box->addItem(QLatin1String("<") + tr("None") + QLatin1String(">"), NULL_ID);
3045 
3046  const QVector<quint32> anchorPoints = GetListInternals<quint32>(ui->anchorPoints_ListWidget);
3047 
3048  for (int i = 0; i < anchorPoints.size(); ++i)
3049  {
3050  const QSharedPointer<VGObject> anchorPoint = data->GetGObject(anchorPoints.at(i));
3051  box->addItem(anchorPoint->name(), anchorPoints.at(i));
3052  }
3053 
3054  const int index = ui->nodes_ComboBox->findData(currentId);
3055  if (index != -1)
3056  {
3057  box->setCurrentIndex(index);
3058  }
3059 }
3060 
3061 //---------------------------------------------------------------------------------------------------------------------
3063 {
3064  ui->comboBoxIncludeType->clear();
3065 
3066  ui->comboBoxIncludeType->addItem(tr("main path"),
3067  static_cast<unsigned char>(PiecePathIncludeType::AsMainPath));
3068  ui->comboBoxIncludeType->addItem(tr("custom seam allowance"),
3069  static_cast<unsigned char>(PiecePathIncludeType::AsCustomSA));
3070 }
3071 
3072 //---------------------------------------------------------------------------------------------------------------------
3074 {
3075  ui->internalPaths_ListWidget->setContextMenuPolicy(Qt::CustomContextMenu);
3076  connect(ui->internalPaths_ListWidget, &QListWidget::customContextMenuRequested, this,
3078 }
3079 
3080 //---------------------------------------------------------------------------------------------------------------------
3082 {
3083  ui->pieceName_LineEdit->setClearButtonEnabled(true);
3084  ui->letter_LineEdit->setClearButtonEnabled(true);
3085  ui->annotation_LineEdit->setClearButtonEnabled(true);
3086 
3087  QColor color = QColor(Qt::white);
3088  ui->color_Label->setText(color.name());
3089  ui->color_Label->setPalette(QPalette(color));
3090 
3091  connect(ui->pieceName_LineEdit, &QLineEdit::textChanged, this, &PatternPieceDialog::pieceNameChanged);
3092  connect(ui->colorPicker_ToolButton, &QToolButton::clicked, this, &PatternPieceDialog::pieceColorChanged);
3093 }
3094 
3095 //---------------------------------------------------------------------------------------------------------------------
3097 {
3098  //Piece label
3099  ui->pieceLabel_GroupBox->setChecked(qApp->Settings()->showPieceLabels());
3100 
3101  ui->pieceLabelWidthFormula_LineEdit->setPlainText(QString::number(qApp->Settings()->getDefaultLabelWidth()));
3102  ui->pieceLabelHeightFormula_LineEdit->setPlainText(QString::number(qApp->Settings()->getDefaultLabelHeight()));
3103 
3104  m_pieceLabelWidthBaseHeight = ui->pieceLabelWidthFormula_LineEdit->height();
3105  m_pieceLabelHeightBaseHeight = ui->pieceLabelHeightFormula_LineEdit->height();
3106  m_pieceLabelAngleBaseHeight = ui->pieceLabelAngleFormula_LineEdit->height();
3107 
3108  connect(ui->pieceLabel_GroupBox, &QGroupBox::toggled, this, &PatternPieceDialog::enabledPieceLabel);
3109  initAnchorPoint(ui->pieceLabelCenterAnchor_ComboBox);
3110  initAnchorPoint(ui->pieceLabelTopLeftAnchor_ComboBox);
3111  initAnchorPoint(ui->pieceLabelBottomRightAnchor_ComboBox);
3112 
3113  connect(ui->pieceLabelTopLeftAnchor_ComboBox, &QComboBox::currentTextChanged,
3115 
3116  connect(ui->pieceLabelBottomRightAnchor_ComboBox, &QComboBox::currentTextChanged,
3118 
3119  connect(ui->pieceLabelWidth_PushButton, &QPushButton::clicked,
3121  connect(ui->pieceLabelHeght_PushButton, &QPushButton::clicked,
3123  connect(ui->pieceLabelAngle_PushButton, &QPushButton::clicked,
3125 
3126  connect(ui->pieceLabelWidthFormula_LineEdit, &QPlainTextEdit::textChanged, this,
3128  connect(ui->pieceLabelHeightFormula_LineEdit, &QPlainTextEdit::textChanged, this,
3130  connect(ui->pieceLabelAngleFormula_LineEdit, &QPlainTextEdit::textChanged, this,
3132 
3133  connect(ui->showPieceLabelWidth_PushButton, &QPushButton::clicked,
3135  connect(ui->showPieceLabelHeight_PushButton, &QPushButton::clicked,
3137  connect(ui->showPieceLabelAngle_PushButton, &QPushButton::clicked,
3139 
3140  connect(ui->editPieceLabel_PushButton, &QPushButton::clicked, this, &PatternPieceDialog::editPieceLabel);
3141 
3142  if (m_pieceLabelLines.isEmpty())
3143  {
3144  VLabelTemplate labelTemplate;
3145  QString filename = qApp->Settings()->getDefaultPatternTemplate();
3146  if (QFileInfo(filename).exists())
3147  {
3148  labelTemplate.setXMLContent(VLabelTemplateConverter(filename).Convert());
3149  m_pieceLabelLines = labelTemplate.ReadLines();
3150  }
3151  }
3152 
3154 
3155  //Pattern label
3156  ui->patternLabel_GroupBox->setChecked(qApp->Settings()->showPatternLabels());
3157 
3158  ui->patternLabelWidthFormula_LineEdit->setPlainText(QString::number(qApp->Settings()->getDefaultLabelWidth()));
3159  ui->patternLabelHeightFormula_LineEdit->setPlainText(QString::number(qApp->Settings()->getDefaultLabelHeight()));
3160 
3161  m_patternLabelWidthBaseHeight = ui->patternLabelWidthFormula_LineEdit->height();
3162  m_patternLabelHeightBaseHeight = ui->patternLabelHeightFormula_LineEdit->height();
3163  m_patternLabelAngleBaseHeight = ui->patternLabelAngleFormula_LineEdit->height();
3164 
3165  connect(ui->patternLabel_GroupBox, &QGroupBox::toggled, this, &PatternPieceDialog::enabledPatternLabel);
3166  initAnchorPoint(ui->patternLabelCenterAnchor_ComboBox);
3167  initAnchorPoint(ui->patternLabelTopLeftAnchor_ComboBox);
3168  initAnchorPoint(ui->patternLabelBottomRightAnchor_ComboBox);
3169 
3170  connect(ui->patternLabelTopLeftAnchor_ComboBox, &QComboBox::currentTextChanged,
3172 
3173  connect(ui->patternLabelBottomRightAnchor_ComboBox, &QComboBox::currentTextChanged,
3175 
3176  connect(ui->patternLabelWidth_PushButton, &QPushButton::clicked,
3178  connect(ui->patternLabelHeght_PushButton, &QPushButton::clicked,
3180  connect(ui->patternLabelAngle_PushButton, &QPushButton::clicked,
3182 
3183  connect(ui->patternLabelWidthFormula_LineEdit, &QPlainTextEdit::textChanged, this,
3185  connect(ui->patternLabelHeightFormula_LineEdit, &QPlainTextEdit::textChanged, this,
3187  connect(ui->patternLabelAngleFormula_LineEdit, &QPlainTextEdit::textChanged, this,
3189 
3190  connect(ui->showPatternLabelWidth_PushButton, &QPushButton::clicked,
3192  connect(ui->showPatternLabelHeight_PushButton, &QPushButton::clicked,
3194  connect(ui->showPatternLabelAngle_PushButton, &QPushButton::clicked,
3196 
3197  connect(ui->editPatternLabel_PushButton, &QPushButton::clicked, this, &PatternPieceDialog::editPatternLabel);
3198 
3199  m_patternLabelLines = qApp->getCurrentDocument()->getPatternLabelTemplate();
3200 
3201  if (m_patternLabelLines.isEmpty())
3202  {
3203  VLabelTemplate labelTemplate;
3204  QString filename = qApp->Settings()->getDefaultPatternTemplate();
3205  if (QFileInfo(filename).exists())
3206  {
3207  labelTemplate.setXMLContent(VLabelTemplateConverter(filename).Convert());
3208  m_patternLabelLines = labelTemplate.ReadLines();
3209  qApp->getCurrentDocument()->setPatternLabelTemplate(m_patternLabelLines);
3210  }
3211  }
3212 
3214 
3215  ui->pieceName_LineEdit->setText(createPieceName());
3216 }
3217 
3218 //---------------------------------------------------------------------------------------------------------------------
3220 {
3221  ui->grainline_GroupBox->setChecked(qApp->Settings()->getDefaultGrainlineVisibilty());
3222 
3223  ui->lengthFormula_LineEdit->setPlainText(QString::number(qApp->Settings()->getDefaultGrainlineLength()));
3224 
3225  connect(ui->grainline_GroupBox, &QGroupBox::toggled, this, &PatternPieceDialog::enabledGrainline);
3226  connect(ui->rotation_PushButton, &QPushButton::clicked, this, &PatternPieceDialog::editGrainlineFormula);
3227  connect(ui->length_PushButton, &QPushButton::clicked, this, &PatternPieceDialog::editGrainlineFormula);
3228  connect(ui->lengthFormula_LineEdit, &QPlainTextEdit::textChanged, this,
3230 
3231  connect(ui->rotationFormula_LineEdit, &QPlainTextEdit::textChanged, this,
3233 
3234  connect(ui->showRotation_PushButton, &QPushButton::clicked, this,
3236 
3237  connect(ui->showLength_PushButton, &QPushButton::clicked, this,
3239 
3240  enabledGrainline();
3241 
3242  ui->arrow_ComboBox->addItem(tr("Both"));
3243  ui->arrow_ComboBox->addItem(tr("Just front"));
3244  ui->arrow_ComboBox->addItem(tr("Just rear"));
3245 
3246  m_rotationBaseHeight = ui->rotationFormula_LineEdit->height();
3247  m_lengthBaseHeight = ui->lengthFormula_LineEdit->height();
3248 
3249  initAnchorPoint(ui->grainlineCenterAnchor_ComboBox);
3250  initAnchorPoint(ui->grainlineTopAnchor_ComboBox);
3251  initAnchorPoint(ui->grainlineBottomAnchor_ComboBox);
3252 
3253  connect(ui->grainlineTopAnchor_ComboBox, &QComboBox::currentTextChanged,
3255 
3256  connect(ui->grainlineBottomAnchor_ComboBox, &QComboBox::currentTextChanged,
3258 }
3259 
3260 //---------------------------------------------------------------------------------------------------------------------
3262 {
3263  ui->anchorPoints_ListWidget->setContextMenuPolicy(Qt::CustomContextMenu);
3264  connect(ui->anchorPoints_ListWidget, &QListWidget::customContextMenuRequested, this,
3266 }
3267 
3268 //---------------------------------------------------------------------------------------------------------------------
3270 {
3272 
3273  ui->notchLength_DoubleSpinBox->setValue(qApp->Settings()->getDefaultNotchLength());
3274  ui->notchWidth_DoubleSpinBox->setValue(qApp->Settings()->getDefaultNotchWidth());
3275  ui->showNotch_CheckBox->setChecked(qApp->Settings()->showSeamAllowanceNotch());
3276  ui->showSeamlineNotch_CheckBox->setChecked(qApp->Settings()->showSeamlineNotch());
3277 
3278  connect(ui->notches_ComboBox, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
3280 
3281  connect(ui->notchType_ButtonGroup, &QButtonGroup::idClicked,
3283 
3284  connect(ui->notchSubType_ButtonGroup, &QButtonGroup::idClicked,
3286 
3287  connect(ui->showNotch_CheckBox, &QCheckBox::stateChanged, this,
3289 
3290  connect(ui->showSeamlineNotch_CheckBox, &QCheckBox::stateChanged, this,
3292 
3293  connect(ui->notchLength_DoubleSpinBox, QOverload<double>::of(&QDoubleSpinBox::valueChanged),
3295 
3296  connect(ui->resetLength_PushButton, &QPushButton::clicked, this, &PatternPieceDialog::resetNotchLength);
3297 
3298  connect(ui->notchWidth_DoubleSpinBox, QOverload<double>::of(&QDoubleSpinBox::valueChanged),
3300 
3301  connect(ui->resetWidth_PushButton, &QPushButton::clicked, this, &PatternPieceDialog::resetNotchWidth);
3302 
3303  connect(ui->notchAngle_DoubleSpinBox, QOverload<double>::of(&QDoubleSpinBox::valueChanged),
3305 
3306  connect(ui->resetAngle_PushButton, &QPushButton::clicked, this, &PatternPieceDialog::resetNotchAngle);
3307 
3308  connect(ui->notchCount_SpinBox, QOverload<int>::of(&QSpinBox::valueChanged),
3310 }
3311 
3312 //---------------------------------------------------------------------------------------------------------------------
3314 {
3315  initAnchorPoint(ui->grainlineCenterAnchor_ComboBox);
3316  initAnchorPoint(ui->grainlineTopAnchor_ComboBox);
3317  initAnchorPoint(ui->grainlineBottomAnchor_ComboBox);
3318 
3319  initAnchorPoint(ui->pieceLabelCenterAnchor_ComboBox);
3320  initAnchorPoint(ui->pieceLabelTopLeftAnchor_ComboBox);
3321  initAnchorPoint(ui->pieceLabelBottomRightAnchor_ComboBox);
3322 
3323  initAnchorPoint(ui->patternLabelCenterAnchor_ComboBox);
3324  initAnchorPoint(ui->patternLabelTopLeftAnchor_ComboBox);
3325  initAnchorPoint(ui->patternLabelBottomRightAnchor_ComboBox);
3326 }
3327 
3328 //---------------------------------------------------------------------------------------------------------------------
3330 {
3331  QString width = ui->widthFormula_PlainTextEdit->toPlainText();
3332  width.replace("\n", " ");
3333  return qApp->TrVars()->TryFormulaFromUser(width, qApp->Settings()->GetOsSeparator());
3334 }
3335 
3336 //---------------------------------------------------------------------------------------------------------------------
3338 {
3339  const QString width = qApp->TrVars()->FormulaToUser(formula, qApp->Settings()->GetOsSeparator());
3340  //Increase textedit box height if needed.
3341  if (width.length() > 80)
3342  {
3344  }
3345  ui->widthFormula_PlainTextEdit->setPlainText(width);
3346 
3347  PatternPieceVisual *path = qobject_cast<PatternPieceVisual *>(vis);
3348  SCASSERT(path != nullptr)
3349  const VPiece p = CreatePiece();
3350  path->SetPiece(p);
3351 
3352  MoveCursorToEnd(ui->widthFormula_PlainTextEdit);
3353 }
3354 
3355 //---------------------------------------------------------------------------------------------------------------------
3357 {
3358  const int row = ui->customSeamAllowance_ListWidget->currentRow();
3359  if (ui->customSeamAllowance_ListWidget->count() == 0 || row == -1)
3360  {
3361  return;
3362  }
3363 
3364  QListWidgetItem *item = ui->customSeamAllowance_ListWidget->item(row);
3365  SCASSERT(item != nullptr);
3366  const CustomSARecord record = qvariant_cast<CustomSARecord>(item->data(Qt::UserRole));
3367  item->setText(getPathName(record.path, record.reverse));
3368 }
3369 
3370 //---------------------------------------------------------------------------------------------------------------------
3372 {
3373  const int row = ui->internalPaths_ListWidget->currentRow();
3374  if (ui->internalPaths_ListWidget->count() == 0 || row == -1)
3375  {
3376  return;
3377  }
3378 
3379  QListWidgetItem *item = ui->internalPaths_ListWidget->item(row);
3380  SCASSERT(item != nullptr);
3381  const quint32 path = qvariant_cast<quint32>(item->data(Qt::UserRole));
3382  item->setText(getPathName(path));
3383 }
3384 
3385 //---------------------------------------------------------------------------------------------------------------------
3386 void PatternPieceDialog::setGrainlineAngle(QString angleFormula)
3387 {
3388  if (angleFormula.isEmpty())
3389  {
3390  angleFormula = QString("0");
3391  }
3392 
3393  const QString formula = qApp->TrVars()->FormulaToUser(angleFormula, qApp->Settings()->GetOsSeparator());
3394  //Increase textedit box height if needed.
3395  if (formula.length() > 80)
3396  {
3397  this->expandGrainlineRotation();
3398  }
3399  ui->rotationFormula_LineEdit->setPlainText(formula);
3400 
3401  MoveCursorToEnd(ui->rotationFormula_LineEdit);
3402 }
3403 
3404 //---------------------------------------------------------------------------------------------------------------------
3405 void PatternPieceDialog::setGrainlineLength(QString lengthFormula)
3406 {
3407  if (lengthFormula.isEmpty())
3408  {
3409  lengthFormula = QString().setNum(UnitConvertor(1, Unit::Cm, *data->GetPatternUnit()));
3410  }
3411 
3412  const QString formula = qApp->TrVars()->FormulaToUser(lengthFormula, qApp->Settings()->GetOsSeparator());
3413  //Increase textedit box height if needed.
3414  if (formula.length() > 80)
3415  {
3416  this->expandGrainlineLength();
3417  }
3418 
3419  ui->lengthFormula_LineEdit->setPlainText(formula);
3420 
3421  MoveCursorToEnd(ui->lengthFormula_LineEdit);
3422 }
3423 
3424 //---------------------------------------------------------------------------------------------------------------------
3425 void PatternPieceDialog::setPieceLabelWidth(QString widthFormula)
3426 {
3427  if (widthFormula.isEmpty())
3428  {
3429  widthFormula = QString().setNum(UnitConvertor(1, Unit::Cm, *data->GetPatternUnit()));
3430  }
3431 
3432  const QString formula = qApp->TrVars()->FormulaToUser(widthFormula, qApp->Settings()->GetOsSeparator());
3433  //Increase textedit box height if needed.
3434  if (formula.length() > 80)
3435  {
3436  this->expandPieceLabelWidth();
3437  }
3438 
3439  ui->pieceLabelWidthFormula_LineEdit->setPlainText(formula);
3440 
3441  MoveCursorToEnd(ui->pieceLabelWidthFormula_LineEdit);
3442 }
3443 
3444 //---------------------------------------------------------------------------------------------------------------------
3445 void PatternPieceDialog::setPieceLabelHeight(QString heightFormula)
3446 {
3447  if (heightFormula.isEmpty())
3448  {
3449  heightFormula = QString().setNum(UnitConvertor(1, Unit::Cm, *data->GetPatternUnit()));
3450  }
3451 
3452  const QString formula = qApp->TrVars()->FormulaToUser(heightFormula, qApp->Settings()->GetOsSeparator());
3453  //Increase textedit box height if needed.
3454  if (formula.length() > 80)
3455  {
3456  this->expandPieceLabelHeight();
3457  }
3458 
3459  ui->pieceLabelHeightFormula_LineEdit->setPlainText(formula);
3460 
3461  MoveCursorToEnd(ui->pieceLabelHeightFormula_LineEdit);
3462 }
3463 
3464 //---------------------------------------------------------------------------------------------------------------------
3465 void PatternPieceDialog::setPieceLabelAngle(QString angleFormula)
3466 {
3467  if (angleFormula.isEmpty())
3468  {
3469  angleFormula = QString("0");
3470  }
3471 
3472  const QString formula = qApp->TrVars()->FormulaToUser(angleFormula, qApp->Settings()->GetOsSeparator());
3473  //Increase textedit box height if needed.
3474  if (formula.length() > 80)
3475  {
3476  this->expandPieceLabelAngle();
3477  }
3478 
3479  ui->pieceLabelAngleFormula_LineEdit->setPlainText(formula);
3480 
3481  MoveCursorToEnd(ui->pieceLabelAngleFormula_LineEdit);
3482 }
3483 
3484 //---------------------------------------------------------------------------------------------------------------------
3486 {
3487  if (widthFormula.isEmpty())
3488  {
3489  widthFormula = QString().setNum(UnitConvertor(1, Unit::Cm, *data->GetPatternUnit()));
3490  }
3491 
3492  const QString formula = qApp->TrVars()->FormulaToUser(widthFormula, qApp->Settings()->GetOsSeparator());
3493  //Increase textedit box height if needed.
3494  if (formula.length() > 80)
3495  {
3496  this->expandPatternLabelWidth();
3497  }
3498 
3499  ui->patternLabelWidthFormula_LineEdit->setPlainText(formula);
3500 
3501  MoveCursorToEnd(ui->patternLabelWidthFormula_LineEdit);
3502 }
3503 
3504 //---------------------------------------------------------------------------------------------------------------------
3506 {
3507  if (heightFormula.isEmpty())
3508  {
3509  heightFormula = QString().setNum(UnitConvertor(1, Unit::Cm, *data->GetPatternUnit()));
3510  }
3511 
3512  const QString formula = qApp->TrVars()->FormulaToUser(heightFormula, qApp->Settings()->GetOsSeparator());
3513  //Increase textedit box height if needed.
3514  if (formula.length() > 80)
3515  {
3516  this->expandPatternLabelHeight();
3517  }
3518 
3519  ui->patternLabelHeightFormula_LineEdit->setPlainText(formula);
3520 
3521  MoveCursorToEnd(ui->patternLabelHeightFormula_LineEdit);
3522 }
3523 
3524 //---------------------------------------------------------------------------------------------------------------------
3526 {
3527  if (angleFormula.isEmpty())
3528  {
3529  angleFormula = QString("0");
3530  }
3531 
3532  const QString formula = qApp->TrVars()->FormulaToUser(angleFormula, qApp->Settings()->GetOsSeparator());
3533  //Increase textedit box height if needed.
3534  if (formula.length() > 80)
3535  {
3536  this->expandPatternLabelAngle();
3537  }
3538 
3539  ui->patternLabelAngleFormula_LineEdit->setPlainText(formula);
3540 
3541  MoveCursorToEnd(ui->patternLabelAngleFormula_LineEdit);
3542 }
3543 
3544 //---------------------------------------------------------------------------------------------------------------------
3546 {
3547  if (m_anchorPoints.isNull())
3548  {
3550  }
3551 
3552  m_anchorPoints->setAnchors(GetListInternals<quint32>(ui->anchorPoints_ListWidget));
3553 
3554  if (!qApp->getCurrentScene()->items().contains(m_anchorPoints))
3555  {
3556  m_anchorPoints->VisualMode(NULL_ID);
3557  m_anchorPoints->setZValue(10); // anchor points should be on top
3558  PatternPieceTool *tool = qobject_cast<PatternPieceTool*>(VAbstractPattern::getTool(toolId));
3559  SCASSERT(tool != nullptr);
3560  m_anchorPoints->setParentItem(tool);
3561  }
3562  else
3563  {
3564  m_anchorPoints->RefreshGeometry();
3565  }
3566 }
3567 
3568 //---------------------------------------------------------------------------------------------------------------------
3570 {
3571  ui->moveTop_ToolButton->setEnabled(false);
3572  ui->moveUp_ToolButton->setEnabled(false);
3573  ui->moveDown_ToolButton->setEnabled(false);
3574  ui->moveBottom_ToolButton->setEnabled(false);
3575 
3576  if (ui->mainPath_ListWidget->count() > 1)
3577  {
3578  if (ui->mainPath_ListWidget->currentRow() == 0)
3579  {
3580  ui->moveDown_ToolButton->setEnabled(true);
3581  ui->moveBottom_ToolButton->setEnabled(true);
3582  }
3583  else if (ui->mainPath_ListWidget->currentRow() == ui->mainPath_ListWidget->count() - 1)
3584  {
3585  ui->moveTop_ToolButton->setEnabled(true);
3586  ui->moveUp_ToolButton->setEnabled(true);
3587  }
3588  else
3589  {
3590  ui->moveTop_ToolButton->setEnabled(true);
3591  ui->moveUp_ToolButton->setEnabled(true);
3592  ui->moveDown_ToolButton->setEnabled(true);
3593  ui->moveBottom_ToolButton->setEnabled(true);
3594  }
3595  }
3596 }
3597 
3598 //---------------------------------------------------------------------------------------------------------------------
3600 {
3601  QList<VPiece> pieces = data->DataPieces()->values();
3602  QStringList pieceNames;
3603 
3604  for (int i = 0; i < pieces.size(); ++i)
3605  {
3606  pieceNames.append(pieces.at(i).GetName());
3607  }
3608 
3609  const QString defaultName = tr("PatternPiece");
3610  QString pieceName = defaultName;
3611  int i = 0;
3612 
3613  while(pieceNames.contains(pieceName))
3614  {
3615  pieceName = defaultName + QString("_%1").arg(++i);
3616  }
3617  return pieceName;
3618 }
3619 
3620 //---------------------------------------------------------------------------------------------------------------------
3621 /*
3622  * @brief Reverses the selected node points if the node is a curve.
3623  * @param rowItem list widget item of the selected row.
3624  */
3625  void PatternPieceDialog::reverseNode(QListWidgetItem *rowItem)
3626 {
3627  VPieceNode rowNode = qvariant_cast<VPieceNode>(rowItem->data(Qt::UserRole));
3628  if (rowNode.GetTypeTool() != Tool::NodePoint)
3629  {
3630  rowNode.SetReverse(!rowNode.GetReverse());
3631  NodeInfo info;
3632  info = getNodeInfo(rowNode, true);
3633  rowItem->setData(Qt::UserRole, QVariant::fromValue(rowNode));
3634  rowItem->setIcon(QIcon(info.icon));
3635  rowItem->setText(info.name);
3636  }
3637 }
3638 
3639 //---------------------------------------------------------------------------------------------------------------------
3640 /*
3641  * @brief Duplcates the selected node and adds it excluded at the end of the list widget.
3642  * @param rowItem list widget item of the selected row.
3643  */
3644  void PatternPieceDialog::duplicateNode(QListWidgetItem *rowItem)
3645 {
3646  VPieceNode rowNode = qvariant_cast<VPieceNode>(rowItem->data(Qt::UserRole));
3647  if (rowNode.GetTypeTool() != Tool::NodePoint)
3648  {
3649  rowNode.SetExcluded(true);
3650  newNodeItem(ui->mainPath_ListWidget, rowNode, true, true);
3651  }
3652 }
3653 
3654 //---------------------------------------------------------------------------------------------------------------------
3655 /*
3656  * @brief Toggles the exclude state of the selected node.
3657  * @param rowItem list widget item of the selected row.
3658  */
3659  void PatternPieceDialog::excludeNode(QListWidgetItem *rowItem)
3660 {
3661  NodeInfo info;
3662  VPieceNode rowNode = qvariant_cast<VPieceNode>(rowItem->data(Qt::UserRole));
3663  rowNode.SetExcluded(!rowNode.isExcluded());
3664  info = getNodeInfo(rowNode, true);
3665  rowItem->setData(Qt::UserRole, QVariant::fromValue(rowNode));
3666  rowItem->setIcon(QIcon(info.icon));
3667  rowItem->setText(info.name);
3668  rowItem->setFont(NodeFont(rowNode.isExcluded()));
3669 }
3670 
3671 //---------------------------------------------------------------------------------------------------------------------
3672 /*
3673  * @brief Sets the notch type of the node of the selected widget item.
3674  * @param rowItem list widget item of the selected row.
3675  * @param notchType of the selected submenu item.
3676  */
3677 void PatternPieceDialog::setNotch(QListWidgetItem *rowItem, bool isNotch, NotchType notchType)
3678 {
3679  VPieceNode rowNode = qvariant_cast<VPieceNode>(rowItem->data(Qt::UserRole));
3680  if (rowNode.GetTypeTool() == Tool::NodePoint)
3681  {
3682  rowNode.setNotch(isNotch);
3683  rowNode.setNotchType(notchType);
3684  NodeInfo info;
3685  info = getNodeInfo(rowNode, true);
3686  rowItem->setData(Qt::UserRole, QVariant::fromValue(rowNode));
3687  rowItem->setIcon(QIcon(info.icon));
3688  rowItem->setText(info.name);
3689  }
3690 }
3691 
3692 void PatternPieceDialog::setCurrentText(QComboBox *box, const QString &text) const
3693 {
3694  SCASSERT(box != nullptr)
3695  const qint32 index = box->findText(text);
3696  if (index != -1)
3697  {
3698  box->setCurrentIndex(index);
3699  }
3700  else
3701  {
3702  box->setCurrentIndex(0);
3703  }
3704 }
3705 
3706 qreal PatternPieceDialog::getFormulaValue(QPlainTextEdit *text) const
3707 {
3708  Calculator calculation;
3709  QString formula = text->toPlainText().simplified();
3710  formula.replace("\n", " ");
3711  formula = qApp->TrVars()->FormulaFromUser(formula, qApp->Settings()->GetOsSeparator());
3712  return ToPixel(calculation.EvalFormula(data->DataVariables(), formula), *data->GetPatternUnit());
3713 }
The Calculator class for calculation formula.
Definition: calculator.h:84
qreal EvalFormula(const QHash< QString, QSharedPointer< VInternalVariable > > *vars, const QString &formula)
eval calculate formula.
Definition: calculator.cpp:96
VPiecePath GetPiecePath() 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
const QColor okColor
Definition: dialogtool.h:219
static bool isFirstPointSameAsLast(QListWidget *listWidget)
Definition: dialogtool.cpp:552
void ToolTip(const QString &toolTip)
ToolTip emit tooltipe for tool.
void DialogClosed(int result)
DialogClosed signal dialog closed.
bool flagName
flagName true if name is correct
Definition: dialogtool.h:183
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
static bool doublePointsExist(QListWidget *listWidget)
Definition: dialogtool.cpp:565
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
NodeInfo getNodeInfo(const VPieceNode &node, bool showNotch=false) const
Definition: dialogtool.cpp:628
const QColor errorColor
Definition: dialogtool.h:220
void newNodeItem(QListWidget *listWidget, const VPieceNode &node, bool nodeExcluded=true, bool isDuplicate=false)
Definition: dialogtool.cpp:679
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
QPushButton * apply_Button
apply_Button button apply
Definition: dialogtool.h:202
bool isInitialized
isInitialized true if window is initialized
Definition: dialogtool.h:180
quint32 toolId
Definition: dialogtool.h:225
static QFont NodeFont(bool nodeExcluded)
Definition: dialogtool.cpp:618
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
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
bool prepare
prepare show if we prepare. Show dialog after finish working with visual part of tool
Definition: dialogtool.h:228
static bool isEachPointNameUnique(QListWidget *listWidget)
Definition: dialogtool.cpp:583
QLabel * labelResultCalculation
labelResultCalculation label with result of calculation
Definition: dialogtool.h:211
void initializeNodeAngles(QComboBox *box)
Definition: dialogtool.cpp:717
virtual bool eventFilter(QObject *object, QEvent *event) Q_DECL_OVERRIDE
Definition: dialogtool.cpp:441
static QString DialogWarningIcon()
Definition: dialogtool.cpp:604
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 GetToolId() const
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 setCheckZero(bool value)
void setCheckLessThanZero(bool value)
void setPostfix(const QString &value)
void SetTemplate(const QVector< VLabelTemplateLine > &lines)
QVector< VLabelTemplateLine > GetTemplate() const
void SetPiece(const VPiece &piece)
void updateNodeBeforeSeamAllowance(const QString &formula)
void notchLengthChanged(qreal value)
void setPieceLabelAngle(QString angleFormula)
virtual void CheckState() Q_DECL_FINAL
SaveData Put dialog data in local variables.
VPieceNode getLastNode() const
void setErrorText(TabOrder tab, QString text)
virtual void closeEvent(QCloseEvent *event) Q_DECL_OVERRIDE
closeEvent handle when dialog cloded
void setSeamAllowanceWidthFormula(const QString &formula)
void showAnchorsContextMenu(const QPoint &pos)
void setPatternLabelHeight(QString heightFormula)
void customSAEndPointChanged(int index)
void setPieceLock(const bool &state)
void setPieceColor(const QString &value)
void notchCountChanged(int value)
void setPieceLabelWidth(QString widthFormula)
virtual void ChosenObject(quint32 id, const SceneObject &type) Q_DECL_OVERRIDE
ChosenObject adds selected object of id and type to list of path items.
void customSAStartPointChanged(int index)
QString getPathName(quint32 path, bool reverse=false) const
VPatternLabelData m_oldGeom
void setGrainlineLength(QString lengthFormula)
void initAnchorPoint(QComboBox *box)
QPointer< PieceAnchorPointVisual > m_anchorPoints
QPointer< DialogTool > m_dialog
void setPatternLabelWidth(QString widthFormula)
virtual bool eventFilter(QObject *object, QEvent *event) Q_DECL_OVERRIDE
void updateNodeAfterSeamAllowance(const QString &formula)
void setNotch(QListWidgetItem *rowItem, bool isNotch, NotchType notchType)
VPieceLabelData m_oldData
void enableApply(bool enable)
QVector< VLabelTemplateLine > m_pieceLabelLines
void enableBuiltIn(bool enable)
void setCurrentAfterSeamAllowance(const QString &formula)
void setCurrentBeforeSeamAllowance(const QString &formula)
void showCustomSAContextMenu(const QPoint &pos)
QString createPieceName() const
void customSeamAllowanceChanged(int row)
qreal getFormulaValue(QPlainTextEdit *text) const
virtual void SaveData() Q_DECL_OVERRIDE
SaveData Put dialog data in local variables.
void setPieceLabelHeight(QString heightFormula)
void duplicateNode(QListWidgetItem *rowItem)
Ui::PatternPieceDialog * ui
void enableSeamAllowance(bool enable)
void notchWidthChanged(qreal value)
void setCurrentText(QComboBox *box, const QString &text) const
void validateObjects(bool value)
void showNotchChanged(int state)
void setPatternLabelAngle(QString angleFormula)
void setInLayout(const bool &state)
void clearErrorText(TabOrder tab, QString text)
void SetPiece(const VPiece &piece)
void newInternalPath(quint32 path)
QVector< VLabelTemplateLine > m_patternLabelLines
void newCustomSeamAllowance(const CustomSARecord &record)
QString getSeamAllowanceWidthFormula() const
void showInternalPathsContextMenu(const QPoint &pos)
void showSeamlineNotchChanged(int state)
void initializeCSAPoint(QComboBox *box)
PatternPieceDialog(const VContainer *data, const quint32 &toolId, QWidget *parent=nullptr)
void pathDialogClosed(int result)
void newAnchorPoint(quint32 anchorPoint)
virtual void ShowDialog(bool click) Q_DECL_OVERRIDE
void newMainPathItem(const VPieceNode &node)
QListWidgetItem * getItemById(quint32 id)
void nodeAngleChanged(int index)
virtual void showEvent(QShowEvent *event) Q_DECL_OVERRIDE
showEvent handle when window show
void setPieceFill(const QString &value)
void reverseNode(QListWidgetItem *rowItem)
void pageChanged(QListWidgetItem *current, QListWidgetItem *previous)
void setGrainlineAngle(QString angleFormula)
void excludeNode(QListWidgetItem *rowItem)
virtual void resizeEvent(QResizeEvent *event) Q_DECL_OVERRIDE
void showMainPathContextMenu(const QPoint &pos)
void customSAIncludeTypeChanged(int index)
void notchAngleChanged(qreal value)
VGrainlineData m_oldGrainline
void SetPiece(const VPiece &piece)
void SetPos(const QPointF &ptPos)
static VDataTool * getTool(quint32 id)
getTool return tool from tool list.
bool IsSeamAllowanceBuiltIn() const
bool IsSeamAllowance() const
bool isHideSeamLine() const
static bool isClockwise(const QVector< QPointF > &points)
void setFill(const QString &value)
void SetMx(qreal value)
qreal GetSAWidth() const
QString getColor() const
qreal GetMx() const
void SetForbidFlipping(bool value)
void setColor(const QString &value)
void setHideSeamLine(bool value)
void SetName(const QString &value)
void SetSeamAllowanceBuiltIn(bool value)
void SetSeamAllowance(bool value)
QString GetName() const
qreal GetMy() const
QString getFill() const
bool IsForbidFlipping() const
void SetMy(qreal value)
The VContainer class container of all variables.
Definition: vcontainer.h:141
void AddVariable(const QString &name, T *var)
Definition: vcontainer.h:327
const QHash< quint32, VPiece > * DataPieces() const
Definition: vcontainer.cpp:712
const QHash< QString, QSharedPointer< VInternalVariable > > * DataVariables() const
Definition: vcontainer.cpp:718
const QSharedPointer< VGObject > GetGObject(quint32 id) const
GetGObject returns a point by id.
Definition: vcontainer.cpp:150
const QSharedPointer< T > GeometricObject(const quint32 &id) const
Definition: vcontainer.h:266
VPiecePath GetPiecePath(quint32 id) const
Definition: vcontainer.cpp:198
const Unit * GetPatternUnit() const
Definition: vcontainer.cpp:599
virtual void setXMLContent(const QString &fileName)
The VExceptionBadId class for exception bad id.
virtual QString ErrorMessage() const Q_DECL_OVERRIDE
ErrorMessage return main error message.
virtual QString DetailedInformation() const
DetailedInformation return detailed information about error.
Definition: vexception.cpp:134
ArrowType GetArrowType() const
void setBottomAnchorPoint(quint32 bottomAnchorPoint)
void SetRotation(const QString &qsRot)
quint32 centerAnchorPoint() const
QString GetRotation() const
void SetLength(const QString &qsLen)
void SetArrowType(ArrowType eAT)
quint32 bottomAnchorPoint() const
quint32 topAnchorPoint() const
void setCenterAnchorPoint(quint32 centerAnchor)
QString GetLength() const
void setTopAnchorPoint(quint32 topAnchorPoint)
The VIncrement class keep data row of increment table.
Definition: vincrement.h:70
QVector< VLabelTemplateLine > ReadLines() const
void setBottomRightAnchorPoint(const quint32 &bottomRightAnchorPoint)
void setCenterAnchorPoint(const quint32 &centerAnchorPoint)
void SetLabelHeight(const QString &dLabelH)
void SetFontSize(int iSize)
quint32 centerAnchorPoint() const
void SetRotation(const QString &dRot)
quint32 topLeftAnchorPoint() const
QString GetLabelWidth() const
void SetLabelWidth(const QString &dLabelW)
QString GetRotation() const
void setTopLeftAnchorPoint(const quint32 &topLeftAnchorPoint)
quint32 bottomRightAnchorPoint() const
QString GetLabelHeight() const
void SetAnnotation(const QString &val)
void SetOnFold(bool onFold)
void SetLabelTemplate(const QVector< VLabelTemplateLine > &lines)
QString GetOrientation() const
void SetTilt(const QString &val)
void SetRotationWay(const QString &val)
void SetFoldPosition(const QString &val)
QVector< VLabelTemplateLine > GetLabelTemplate() const
void SetQuantity(int val)
bool IsOnFold() const
int GetQuantity() const
QString GetRotationWay() const
void SetOrientation(const QString &val)
void SetLetter(const QString &qsLetter)
QString GetAnnotation() const
QString GetTilt() const
QString GetLetter() const
QString GetFoldPosition() const
void setBeforeSAFormula(const QString &formula)
Definition: vpiecenode.cpp:221
void setShowNotch(bool value)
Definition: vpiecenode.cpp:344
void setNotchCount(int notchCount)
Definition: vpiecenode.cpp:399
void SetExcluded(bool exclude)
Definition: vpiecenode.cpp:417
void setNotch(bool notch)
Definition: vpiecenode.cpp:293
Tool GetTypeTool() const
Definition: vpiecenode.cpp:161
bool showNotch() const
Definition: vpiecenode.cpp:338
quint32 GetId() const
Definition: vpiecenode.cpp:149
bool isExcluded() const
Definition: vpiecenode.cpp:411
void setNotchType(NotchType notchType)
Definition: vpiecenode.cpp:320
void setAfterSAFormula(const QString &formula)
Definition: vpiecenode.cpp:263
PieceNodeAngle GetAngleType() const
Definition: vpiecenode.cpp:272
void setNotchLength(qreal notchLength)
Definition: vpiecenode.cpp:363
NotchType getNotchType() const
Definition: vpiecenode.cpp:314
QString GetFormulaSAAfter() const
Definition: vpiecenode.cpp:257
void setNotchWidth(qreal notchWidth)
Definition: vpiecenode.cpp:375
qreal getNotchAngle() const
Definition: vpiecenode.cpp:393
QString GetFormulaSABefore() const
Definition: vpiecenode.cpp:215
bool GetReverse() const
Definition: vpiecenode.cpp:173
void setShowSeamlineNotch(bool value)
Definition: vpiecenode.cpp:356
void SetAngleType(PieceNodeAngle type)
Definition: vpiecenode.cpp:278
qreal getNotchLength() const
Definition: vpiecenode.cpp:369
bool isNotch() const
Definition: vpiecenode.cpp:287
void SetReverse(bool reverse)
Definition: vpiecenode.cpp:179
int getNotchCount() const
Definition: vpiecenode.cpp:405
void setNotchAngle(qreal notchAngle)
Definition: vpiecenode.cpp:387
NotchSubType getNotchSubType() const
Definition: vpiecenode.cpp:326
qreal getNotchWidth() const
Definition: vpiecenode.cpp:381
bool showSeamlineNotch() const
Definition: vpiecenode.cpp:350
void setNotchSubType(NotchSubType notchSubType)
Definition: vpiecenode.cpp:332
QVector< QPointF > PathPoints(const VContainer *data) const
Definition: vpiecepath.cpp:287
qint32 CountNodes() const
Definition: vpiecepath.cpp:209
void SetNodes(const QVector< VPieceNode > &nodes)
Definition: vpiecepath.cpp:233
const VPieceNode & at(int indx) const
Definition: vpiecepath.cpp:221
int indexOfNode(quint32 id) const
Definition: vpiecepath.cpp:507
QString GetName() const
Definition: vpiecepath.cpp:251
Definition: vpiece.h:88
void setIsLocked(bool isLocked)
Definition: vpiece.cpp:394
VPieceLabelData & GetPatternPieceData()
Returns full access to the pattern piece data object.
Definition: vpiece.cpp:532
QVector< CustomSARecord > GetCustomSARecords() const
Definition: vpiece.cpp:444
QString getSeamAllowanceWidthFormula() const
Definition: vpiece.cpp:412
bool isInLayout() const
Definition: vpiece.cpp:376
QVector< quint32 > GetInternalPaths() const
Definition: vpiece.cpp:426
void SetInLayout(bool inLayout)
Definition: vpiece.cpp:382
QVector< quint32 > getAnchors() const
Definition: vpiece.cpp:462
void setAnchors(const QVector< quint32 > &anchors)
Definition: vpiece.cpp:474
void SetCustomSARecords(const QVector< CustomSARecord > &records)
Definition: vpiece.cpp:456
void setSeamAllowanceWidthFormula(const QString &formula, qreal value)
Definition: vpiece.cpp:418
void SetInternalPaths(const QVector< quint32 > &iPaths)
Definition: vpiece.cpp:438
QVector< QPointF > MainPathPoints(const VContainer *data) const
Definition: vpiece.cpp:174
VGrainlineData & GetGrainlineGeometry()
VDetail::GetGrainlineGeometry full access to the grainline geometry object.
Definition: vpiece.cpp:578
VPatternLabelData & GetPatternInfo()
Returns full access to the pattern info geometry object.
Definition: vpiece.cpp:558
bool isLocked() const
Definition: vpiece.cpp:388
VPiecePath GetPath() const
Definition: vpiece.cpp:156
The VPointF class keep data of point.
Definition: vpointf.h:75
Error class of the parser.
const QString & GetMsg() const
Returns the message string for this error.
Unit StrToUnits(const QString &unit)
Definition: def.cpp:670
double ToPixel(double val, const Unit &unit)
Definition: def.cpp:231
const QString degreeSymbol
Definition: def.cpp:196
QString UnitsToStr(const Unit &unit, const bool translate)
UnitsToStr translate unit to string.
Definition: def.cpp:702
NotchType stringToNotchType(const QString &value)
Definition: def.cpp:600
qreal UnitConvertor(qreal value, const Unit &from, const Unit &to)
Definition: def.cpp:269
NotchType
Definition: def.h:123
#define SCASSERT(cond)
Definition: def.h:317
PieceNodeAngle
Definition: def.h:113
NotchSubType
Definition: def.h:137
SceneObject
Definition: def.h:103
@ NodeSplinePath
@ NodeSpline
@ NodeElArc
@ NodeArc
@ NodePoint
PiecePathIncludeType
Definition: def.h:152
ArrowType
Definition: floatitemdef.h:60
const QString FillNone
Definition: ifcdef.cpp:395
const QString currentSeamAllowance
Definition: ifcdef.cpp:442
#define NULL_ID
Definition: ifcdef.h:76
QString getFormulaFromUser(QPlainTextEdit *textEdit)
void enableDefaultButton(QPushButton *defButton, const QString &formula)
@ Grainline
@ SeamAllowance
@ Properties
@ AnchorPoints
The CustomSA struct contains record about custom seam allowanse (SA).
Definition: def.h:510
quint32 endPoint
Definition: def.h:521
quint32 path
Definition: def.h:520
quint32 startPoint
Definition: def.h:519
bool reverse
Definition: def.h:522
PiecePathIncludeType includeType
Definition: def.h:523
QString name
Definition: dialogtool.h:89
QString icon
Definition: dialogtool.h:88
#define qApp
Definition: vapplication.h:67
GOType
Definition: vgeometrydef.h:56
@ SavePiecePathOptions