Seamly2D
Code documentation
dialogmirrorbyline.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  * *
3  * Copyright (C) 2017 Seamly, LLC *
4  * *
5  * https://github.com/fashionfreedom/seamly2d *
6  * *
7  ***************************************************************************
8  **
9  ** Seamly2D is free software: you can redistribute it and/or modify
10  ** it under the terms of the GNU General Public License as published by
11  ** the Free Software Foundation, either version 3 of the License, or
12  ** (at your option) any later version.
13  **
14  ** Seamly2D is distributed in the hope that it will be useful,
15  ** but WITHOUT ANY WARRANTY; without even the implied warranty of
16  ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  ** GNU General Public License for more details.
18  **
19  ** You should have received a copy of the GNU General Public License
20  ** along with Seamly2D. If not, see <http://www.gnu.org/licenses/>.
21  **
22  **************************************************************************
23 
24  ************************************************************************
25  **
26  ** @file dialogmirrorbyline.cpp
27  ** @author Roman Telezhynskyi <dismine(at)gmail.com>
28  ** @date 12 9, 2016
29  **
30  ** @brief
31  ** @copyright
32  ** This source code is part of the Valentine project, a pattern making
33  ** program, whose allow create and modeling patterns of clothing.
34  ** Copyright (C) 2016 Seamly2D project
35  ** <https://github.com/fashionfreedom/seamly2d> All Rights Reserved.
36  **
37  ** Seamly2D is free software: you can redistribute it and/or modify
38  ** it under the terms of the GNU General Public License as published by
39  ** the Free Software Foundation, either version 3 of the License, or
40  ** (at your option) any later version.
41  **
42  ** Seamly2D is distributed in the hope that it will be useful,
43  ** but WITHOUT ANY WARRANTY; without even the implied warranty of
44  ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
45  ** GNU General Public License for more details.
46  **
47  ** You should have received a copy of the GNU General Public License
48  ** along with Seamly2D. If not, see <http://www.gnu.org/licenses/>.
49  **
50  *************************************************************************/
51 
52 #include "dialogmirrorbyline.h"
53 
54 #include <QColor>
55 #include <QComboBox>
56 #include <QDialog>
57 #include <QLabel>
58 #include <QLineEdit>
59 #include <QPointF>
60 #include <QPointer>
61 #include <QPushButton>
62 #include <QRegularExpression>
63 #include <QRegularExpressionMatch>
64 #include <QSharedPointer>
65 #include <QStringList>
66 #include <QToolButton>
67 #include <Qt>
68 #include <new>
69 
70 #include "../../visualization/visualization.h"
71 #include "../../visualization/line/operation/vistoolmirrorbyline.h"
72 #include "../ifc/xml/vabstractpattern.h"
73 #include "../ifc/xml/vdomdocument.h"
74 #include "../qmuparser/qmudef.h"
75 #include "../vgeometry/vpointf.h"
76 #include "../vmisc/vabstractapplication.h"
77 #include "../vmisc/vcommonsettings.h"
78 #include "../vpatterndb/vcontainer.h"
79 #include "../vwidgets/vabstractmainwindow.h"
80 #include "../vwidgets/vmaingraphicsscene.h"
81 #include "ui_dialogmirrorbyline.h"
82 
83 //---------------------------------------------------------------------------------------------------------------------
84 DialogMirrorByLine::DialogMirrorByLine(const VContainer *data, const quint32 &toolId, QWidget *parent)
85  : DialogTool(data, toolId, parent)
86  , ui(new Ui::DialogMirrorByLine)
87  , m_objects()
88  , stage1(true)
89  , m_suffix()
90 {
91  ui->setupUi(this);
92  setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
93  setWindowIcon(QIcon(":/toolicon/32x32/mirror_by_line.png"));
94 
95  ui->suffix_LineEdit->setText(qApp->getCurrentDocument()->GenerateSuffix(qApp->Settings()->getMirrorByLineSuffix()));
96 
98 
99  FillComboBoxPoints(ui->firstLinePoint_ComboBox);
100  FillComboBoxPoints(ui->secondLinePoint_ComboBox);
101 
102  flagName = true;
103  CheckState();
104 
105  connect(ui->suffix_LineEdit, &QLineEdit::textChanged, this, &DialogMirrorByLine::suffixChanged);
106  connect(ui->firstLinePoint_ComboBox, &QComboBox::currentTextChanged, this, &DialogMirrorByLine::pointChanged);
107  connect(ui->secondLinePoint_ComboBox, &QComboBox::currentTextChanged, this, &DialogMirrorByLine::pointChanged);
108 
110 }
111 
112 //---------------------------------------------------------------------------------------------------------------------
114 {
115  delete ui;
116 }
117 
118 //---------------------------------------------------------------------------------------------------------------------
120 {
121  return getCurrentObjectId(ui->firstLinePoint_ComboBox);
122 }
123 
124 //---------------------------------------------------------------------------------------------------------------------
126 {
127  ChangeCurrentData(ui->firstLinePoint_ComboBox, value);
128  VisToolMirrorByLine *operation = qobject_cast<VisToolMirrorByLine *>(vis);
129  SCASSERT(operation != nullptr)
130  operation->setFirstLinePointId(value);
131 }
132 
133 //---------------------------------------------------------------------------------------------------------------------
135 {
136  return getCurrentObjectId(ui->secondLinePoint_ComboBox);
137 }
138 
139 //---------------------------------------------------------------------------------------------------------------------
141 {
142  ChangeCurrentData(ui->secondLinePoint_ComboBox, value);
143  VisToolMirrorByLine *operation = qobject_cast<VisToolMirrorByLine *>(vis);
144  SCASSERT(operation != nullptr)
145  operation->setSecondLinePointId(value);
146 }
147 
148 //---------------------------------------------------------------------------------------------------------------------
150 {
151  return m_suffix;
152 }
153 
154 //---------------------------------------------------------------------------------------------------------------------
155 void DialogMirrorByLine::setSuffix(const QString &value)
156 {
157  m_suffix = value;
158  ui->suffix_LineEdit->setText(value);
159 }
160 
161 //---------------------------------------------------------------------------------------------------------------------
163 {
164  return m_objects;
165 }
166 
167 //---------------------------------------------------------------------------------------------------------------------
169 {
170  m_objects = value;
171 
172  VisToolMirrorByLine *operation = qobject_cast<VisToolMirrorByLine *>(vis);
173  SCASSERT(operation != nullptr)
174  operation->setObjects(sourceToObjects(m_objects));
175 }
176 
177 //---------------------------------------------------------------------------------------------------------------------
179 {
180  if (stage1 && not click)
181  {
182  if (m_objects.isEmpty())
183  {
184  return;
185  }
186 
187  stage1 = false;
188 
189  VMainGraphicsScene *scene = qobject_cast<VMainGraphicsScene *>(qApp->getCurrentScene());
190  SCASSERT(scene != nullptr)
191  scene->clearSelection();
192 
193  VisToolMirrorByLine *operation = qobject_cast<VisToolMirrorByLine *>(vis);
194  SCASSERT(operation != nullptr)
195  operation->setObjects(sourceToObjects(m_objects));
196  operation->VisualMode();
197 
198  scene->ToggleArcSelection(false);
199  scene->ToggleElArcSelection(false);
200  scene->ToggleSplineSelection(false);
201  scene->ToggleSplinePathSelection(false);
202 
203  scene->ToggleArcHover(false);
204  scene->ToggleElArcHover(false);
205  scene->ToggleSplineHover(false);
206  scene->ToggleSplinePathHover(false);
207 
208  qApp->getSceneView()->allowRubberBand(false);
209 
210  emit ToolTip(tr("Select first mirror line point"));
211  }
212  else if (not stage1 && prepare && click)
213  {
214  CheckState();
215  setModal(true);
216  emit ToolTip("");
217  show();
218  }
219 }
220 
221 //---------------------------------------------------------------------------------------------------------------------
222 void DialogMirrorByLine::ChosenObject(quint32 id, const SceneObject &type)
223 {
224  if (not stage1 && not prepare)// After first choose we ignore all objects
225  {
226  if (type == SceneObject::Point)
227  {
228  auto object = std::find_if(m_objects.begin(), m_objects.end(),
229  [id](const SourceItem &item) { return item.id == id; });
230 
231  switch (number)
232  {
233  case 0:
234  if (object != m_objects.end())
235  {
236  emit ToolTip(tr("Select first mirror line point that is not part of the list of objects"));
237  return;
238  }
239 
240  if (SetObject(id, ui->firstLinePoint_ComboBox, tr("Select second mirror line point")))
241  {
242  number++;
243  VisToolMirrorByLine *operation = qobject_cast<VisToolMirrorByLine *>(vis);
244  SCASSERT(operation != nullptr)
245  operation->setFirstLinePointId(id);
246  operation->RefreshGeometry();
247  }
248  break;
249  case 1:
250  if (object != m_objects.end())
251  {
252  emit ToolTip(tr("Select second mirror line point that is not part of the list of objects"));
253  return;
254  }
255 
256  if (getCurrentObjectId(ui->firstLinePoint_ComboBox) != id)
257  {
258  if (SetObject(id, ui->secondLinePoint_ComboBox, ""))
259  {
260  if (flagError)
261  {
262  number = 0;
263  prepare = true;
264 
265  VisToolMirrorByLine *operation = qobject_cast<VisToolMirrorByLine *>(vis);
266  SCASSERT(operation != nullptr)
267  operation->setSecondLinePointId(id);
268  operation->RefreshGeometry();
269  }
270  }
271  }
272  break;
273  default:
274  break;
275  }
276  }
277  }
278 }
279 
280 //---------------------------------------------------------------------------------------------------------------------
281 void DialogMirrorByLine::SelectedObject(bool selected, quint32 id, quint32 tool)
282 {
283  Q_UNUSED(tool)
284  if (stage1)
285  {
286  auto object = std::find_if(m_objects.begin(), m_objects.end(),
287  [id](const SourceItem &item) { return item.id == id; });
288 
289  if (selected)
290  {
291  if (object == m_objects.cend())
292  {
293  SourceItem item;
294  item.id = id;
295  m_objects.append(item);
296  }
297  }
298  else
299  {
300  if (object != m_objects.end())
301  {
302  m_objects.erase(object);
303  }
304  }
305  }
306 }
307 
308 //---------------------------------------------------------------------------------------------------------------------
310 {
311  QLineEdit* edit = qobject_cast<QLineEdit*>(sender());
312  if (edit)
313  {
314  const QString suffix = edit->text();
315  if (suffix.isEmpty())
316  {
317  flagName = false;
318  ChangeColor(ui->suffix_Label, Qt::red);
319  CheckState();
320  return;
321  }
322  else
323  {
324  if (m_suffix != suffix)
325  {
326  QRegularExpression rx(NameRegExp());
327  const QStringList uniqueNames = VContainer::AllUniqueNames();
328  for (int i=0; i < uniqueNames.size(); ++i)
329  {
330  const QString name = uniqueNames.at(i) + suffix;
331  if (not rx.match(name).hasMatch() || not data->IsUnique(name))
332  {
333  flagName = false;
334  ChangeColor(ui->suffix_Label, Qt::red);
335  CheckState();
336  return;
337  }
338  }
339  }
340  }
341 
342  flagName = true;
343  ChangeColor(ui->suffix_Label, okColor);
344  }
345  CheckState();
346 }
347 
348 //---------------------------------------------------------------------------------------------------------------------
350 {
351  SCASSERT(ok_Button != nullptr)
352  ok_Button->setEnabled(flagError && flagName);
353  SCASSERT(apply_Button != nullptr)
354  apply_Button->setEnabled(ok_Button->isEnabled());
355 }
356 
357 //---------------------------------------------------------------------------------------------------------------------
359 {
360  AddVisualization<VisToolMirrorByLine>();
361 }
362 
363 //---------------------------------------------------------------------------------------------------------------------
365 {
366  m_suffix = ui->suffix_LineEdit->text();
367 
368  VisToolMirrorByLine *operation = qobject_cast<VisToolMirrorByLine *>(vis);
369  SCASSERT(operation != nullptr)
370 
371  operation->setObjects(sourceToObjects(m_objects));
374  operation->RefreshGeometry();
375 }
376 
377 //---------------------------------------------------------------------------------------------------------------------
379 {
380  QColor color = okColor;
381  flagError = true;
382  ChangeColor(ui->firstLinePoint_Label, color);
383  ChangeColor(ui->secondLinePoint_Label, color);
384 
385  quint32 id1 = getCurrentObjectId(ui->firstLinePoint_ComboBox);
386  auto objectId1 = std::find_if(m_objects.begin(), m_objects.end(),
387  [id1](const SourceItem &item) { return item.id == id1;});
388 
389  quint32 id2 = getCurrentObjectId(ui->secondLinePoint_ComboBox);
390  auto objectId2 = std::find_if(m_objects.begin(), m_objects.end(),
391  [id2](const SourceItem &item) { return item.id == id2;});
392 
393  if (getCurrentObjectId(ui->firstLinePoint_ComboBox) == getCurrentObjectId(ui->secondLinePoint_ComboBox))
394  {
395  flagError = false;
396  color = errorColor;
397  ChangeColor(ui->firstLinePoint_Label, color);
398  ChangeColor(ui->secondLinePoint_Label, color);
399  }
400  else if (objectId1 != m_objects.end())
401  {
402  flagError = false;
403  color = errorColor;
404  ChangeColor(ui->firstLinePoint_Label, color);
405  }
406  else if (objectId2 != m_objects.end())
407  {
408  flagError = false;
409  color = errorColor;
410  ChangeColor(ui->secondLinePoint_Label, color);
411  }
412 
413  CheckState();
414 }
void setFirstLinePointId(quint32 value)
virtual void SaveData() Q_DECL_OVERRIDE
SaveData Put dialog data in local variables.
QString getSuffix() const
DialogMirrorByLine(const VContainer *data, const quint32 &toolId, QWidget *parent=nullptr)
virtual void SelectedObject(bool selected, quint32 id, quint32 tool) Q_DECL_OVERRIDE
void setSourceObjects(const QVector< SourceItem > &value)
virtual void ShowVisualization() Q_DECL_OVERRIDE
void setSuffix(const QString &value)
quint32 getSecondLinePointId() const
Ui::DialogMirrorByLine * ui
void setSecondLinePointId(quint32 value)
quint32 getFirstLinePointId() const
virtual void CheckState() Q_DECL_FINAL
CheckState enable, when all is correct, or disable, when something wrong, button ok.
virtual void ChosenObject(quint32 id, const SceneObject &type) Q_DECL_OVERRIDE
QVector< SourceItem > getSourceObjects() const
virtual void ShowDialog(bool click) Q_DECL_OVERRIDE
QVector< SourceItem > m_objects
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
void ToolTip(const QString &toolTip)
ToolTip emit tooltipe for tool.
void FillComboBoxPoints(QComboBox *box, FillComboBox rule=FillComboBox::Whole, const quint32 &ch1=NULL_ID, const quint32 &ch2=NULL_ID) const
FillComboBoxPoints fill comboBox list of points.
Definition: dialogtool.cpp:242
bool flagName
flagName true if name is correct
Definition: dialogtool.h:183
QPushButton * ok_Button
ok_Button button ok
Definition: dialogtool.h:199
const QColor errorColor
Definition: dialogtool.h:220
qint32 number
number number of handled objects
Definition: dialogtool.h:234
bool SetObject(const quint32 &id, QComboBox *box, const QString &toolTip)
Definition: dialogtool.cpp:974
QPushButton * apply_Button
apply_Button button apply
Definition: dialogtool.h:202
void initializeOkCancelApply(T *ui)
initializeOkCancelApply initialize OK / Cancel and Apply buttons
Definition: dialogtool.h:365
bool flagError
flagError use this flag if for you do not enought
Definition: dialogtool.h:193
const VContainer * data
data container with data
Definition: dialogtool.h:177
bool prepare
prepare show if we prepare. Show dialog after finish working with visual part of tool
Definition: dialogtool.h:228
QPointer< Visualization > vis
Definition: dialogtool.h:236
void ChangeColor(QWidget *widget, const QColor &color)
quint32 getCurrentObjectId(QComboBox *box) const
getCurrentPointId return current point id stored in combobox
Definition: dialogtool.cpp:959
The VContainer class container of all variables.
Definition: vcontainer.h:141
static bool IsUnique(const QString &name)
Definition: vcontainer.cpp:585
static QStringList AllUniqueNames()
Definition: vcontainer.cpp:591
The VMainGraphicsScene class main scene.
void ToggleArcHover(bool enabled)
void ToggleSplinePathSelection(bool enabled)
void ToggleElArcHover(bool enabled)
void ToggleElArcSelection(bool enabled)
void ToggleSplinePathHover(bool enabled)
void ToggleSplineHover(bool enabled)
void ToggleSplineSelection(bool enabled)
void ToggleArcSelection(bool enabled)
void setObjects(QVector< quint32 > objects)
virtual void VisualMode(const quint32 &pointId=NULL_ID) Q_DECL_OVERRIDE
void setFirstLinePointId(quint32 value)
virtual void RefreshGeometry() Q_DECL_OVERRIDE
void setSecondLinePointId(quint32 value)
#define SCASSERT(cond)
Definition: def.h:317
SceneObject
Definition: def.h:103
QString NameRegExp()
Definition: qmudef.cpp:281
QVector< quint32 > sourceToObjects(const QVector< SourceItem > &source)
#define qApp
Definition: vapplication.h:67