Seamly2D
Code documentation
dialogmirrorbyaxis.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 dialogmirrorbyaxis.cpp
27  ** @author Roman Telezhynskyi <dismine(at)gmail.com>
28  ** @date 16 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 "dialogmirrorbyaxis.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/vistoolmirrorbyaxis.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_dialogmirrorbyaxis.h"
82 
83 //---------------------------------------------------------------------------------------------------------------------
84 DialogMirrorByAxis::DialogMirrorByAxis(const VContainer *data, const quint32 &toolId, QWidget *parent)
85  : DialogTool(data, toolId, parent)
86  , ui(new Ui::DialogMirrorByAxis)
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_axis.png"));
94 
95  ui->suffix_LineEdit->setText(qApp->getCurrentDocument()->GenerateSuffix(qApp->Settings()->getMirrorByAxisSuffix()));
96 
98 
99  FillComboBoxPoints(ui->originPoint_ComboBox);
100  fillComboBoxAxisType(ui->axisType_ComboBox);
101 
102  flagName = true;
103  CheckState();
104 
105  connect(ui->suffix_LineEdit, &QLineEdit::textChanged, this, &DialogMirrorByAxis::suffixChanged);
106  connect(ui->originPoint_ComboBox, &QComboBox::currentTextChanged, this, &DialogMirrorByAxis::pointChanged);
107 
109 }
110 
111 //---------------------------------------------------------------------------------------------------------------------
113 {
114  delete ui;
115 }
116 
117 //---------------------------------------------------------------------------------------------------------------------
119 {
120  return getCurrentObjectId(ui->originPoint_ComboBox);
121 }
122 
123 //---------------------------------------------------------------------------------------------------------------------
125 {
126  ChangeCurrentData(ui->originPoint_ComboBox, value);
127  VisToolMirrorByAxis *operation = qobject_cast<VisToolMirrorByAxis *>(vis);
128  SCASSERT(operation != nullptr)
129  operation->setOriginPointId(value);
130 }
131 
132 //---------------------------------------------------------------------------------------------------------------------
134 {
135  return getCurrentCrossPoint<AxisType>(ui->axisType_ComboBox);
136 }
137 
138 //---------------------------------------------------------------------------------------------------------------------
140 {
141  auto index = ui->axisType_ComboBox->findData(static_cast<int>(type));
142  if (index != -1)
143  {
144  ui->axisType_ComboBox->setCurrentIndex(index);
145 
146  auto operation = qobject_cast<VisToolMirrorByAxis *>(vis);
147  SCASSERT(operation != nullptr)
148  operation->setAxisType(type);
149  }
150 }
151 
152 //---------------------------------------------------------------------------------------------------------------------
154 {
155  return m_suffix;
156 }
157 
158 //---------------------------------------------------------------------------------------------------------------------
159 void DialogMirrorByAxis::setSuffix(const QString &value)
160 {
161  m_suffix = value;
162  ui->suffix_LineEdit->setText(value);
163 }
164 
165 //---------------------------------------------------------------------------------------------------------------------
167 {
168  return m_objects;
169 }
170 
171 //---------------------------------------------------------------------------------------------------------------------
173 {
174  m_objects = value;
175 
176  VisToolMirrorByAxis *operation = qobject_cast<VisToolMirrorByAxis *>(vis);
177  SCASSERT(operation != nullptr)
178  operation->setObjects(sourceToObjects(m_objects));
179 }
180 
181 //---------------------------------------------------------------------------------------------------------------------
183 {
184  if (stage1 && not click)
185  {
186  if (m_objects.isEmpty())
187  {
188  return;
189  }
190 
191  stage1 = false;
192 
193  VMainGraphicsScene *scene = qobject_cast<VMainGraphicsScene *>(qApp->getCurrentScene());
194  SCASSERT(scene != nullptr)
195  scene->clearSelection();
196 
197  VisToolMirrorByAxis *operation = qobject_cast<VisToolMirrorByAxis *>(vis);
198  SCASSERT(operation != nullptr)
199  operation->setObjects(sourceToObjects(m_objects));
200  operation->VisualMode();
201 
202  scene->ToggleArcSelection(false);
203  scene->ToggleElArcSelection(false);
204  scene->ToggleSplineSelection(false);
205  scene->ToggleSplinePathSelection(false);
206 
207  scene->ToggleArcHover(false);
208  scene->ToggleElArcHover(false);
209  scene->ToggleSplineHover(false);
210  scene->ToggleSplinePathHover(false);
211 
212  qApp->getSceneView()->allowRubberBand(false);
213 
214  emit ToolTip(tr("Select axis rotation point"));
215  }
216  else if (not stage1 && prepare && click)
217  {
218  CheckState();
219  setModal(true);
220  emit ToolTip("");
221  show();
222  }
223 }
224 
225 //---------------------------------------------------------------------------------------------------------------------
226 void DialogMirrorByAxis::ChosenObject(quint32 id, const SceneObject &type)
227 {
228  if (not stage1 && not prepare)// After first choose we ignore all objects
229  {
230  if (type == SceneObject::Point)
231  {
232  auto object = std::find_if(m_objects.begin(), m_objects.end(),
233  [id](const SourceItem &item) { return item.id == id; });
234 
235  if (object != m_objects.end())
236  {
237  emit ToolTip(tr("Select axis rotation point that is not part of the list of objects"));
238  return;
239  }
240 
241  if (SetObject(id, ui->originPoint_ComboBox, ""))
242  {
243  VisToolMirrorByAxis *operation = qobject_cast<VisToolMirrorByAxis *>(vis);
244  SCASSERT(operation != nullptr)
245  operation->setOriginPointId(id);
246  operation->RefreshGeometry();
247 
248  prepare = true;
249  }
250  }
251  }
252 }
253 
254 //---------------------------------------------------------------------------------------------------------------------
255 void DialogMirrorByAxis::SelectedObject(bool selected, quint32 id, quint32 tool)
256 {
257  Q_UNUSED(tool)
258  if (stage1)
259  {
260  auto object = std::find_if(m_objects.begin(), m_objects.end(),
261  [id](const SourceItem &item) { return item.id == id; });
262 
263  if (selected)
264  {
265  if (object == m_objects.cend())
266  {
267  SourceItem item;
268  item.id = id;
269  m_objects.append(item);
270  }
271  }
272  else
273  {
274  if (object != m_objects.end())
275  {
276  m_objects.erase(object);
277  }
278  }
279  }
280 }
281 
282 //---------------------------------------------------------------------------------------------------------------------
284 {
285  QLineEdit* edit = qobject_cast<QLineEdit*>(sender());
286  if (edit)
287  {
288  const QString suffix = edit->text();
289  if (suffix.isEmpty())
290  {
291  flagName = false;
292  ChangeColor(ui->suffix_Label, Qt::red);
293  CheckState();
294  return;
295  }
296  else
297  {
298  if (m_suffix != suffix)
299  {
300  QRegularExpression rx(NameRegExp());
301  const QStringList uniqueNames = VContainer::AllUniqueNames();
302  for (int i=0; i < uniqueNames.size(); ++i)
303  {
304  const QString name = uniqueNames.at(i) + suffix;
305  if (not rx.match(name).hasMatch() || not data->IsUnique(name))
306  {
307  flagName = false;
308  ChangeColor(ui->suffix_Label, Qt::red);
309  CheckState();
310  return;
311  }
312  }
313  }
314  }
315 
316  flagName = true;
317  ChangeColor(ui->suffix_Label, okColor);
318  }
319  CheckState();
320 }
321 
322 //---------------------------------------------------------------------------------------------------------------------
324 {
325  SCASSERT(ok_Button != nullptr)
326  ok_Button->setEnabled(flagError && flagName);
327  SCASSERT(apply_Button != nullptr)
328  apply_Button->setEnabled(ok_Button->isEnabled());
329 }
330 
331 //---------------------------------------------------------------------------------------------------------------------
333 {
334  AddVisualization<VisToolMirrorByAxis>();
335 }
336 
337 //---------------------------------------------------------------------------------------------------------------------
339 {
340  m_suffix = ui->suffix_LineEdit->text();
341 
342  VisToolMirrorByAxis *operation = qobject_cast<VisToolMirrorByAxis *>(vis);
343  SCASSERT(operation != nullptr)
344 
345  operation->setObjects(sourceToObjects(m_objects));
346  operation->setOriginPointId(getOriginPointId());
347  operation->setAxisType(getAxisType());
348  operation->RefreshGeometry();
349 }
350 
351 //---------------------------------------------------------------------------------------------------------------------
353 {
354  QColor color = okColor;
355  quint32 id = getCurrentObjectId(ui->originPoint_ComboBox);
356  auto objectId = std::find_if(m_objects.begin(), m_objects.end(),
357  [id](const SourceItem &item) { return item.id == id;});
358 
359  if (objectId != m_objects.end())
360  {
361  flagError = false;
362  color = errorColor;
363  }
364  else
365  {
366  flagError = true;
367  color = okColor;
368  }
369  ChangeColor(ui->originPoint_Label, color);
370  CheckState();
371 }
372 
373 //---------------------------------------------------------------------------------------------------------------------
375 {
376  SCASSERT(box != nullptr)
377 
378  box->addItem(tr("Vertical axis"), QVariant(static_cast<int>(AxisType::VerticalAxis)));
379  box->addItem(tr("Horizontal axis"), QVariant(static_cast<int>(AxisType::HorizontalAxis)));
380 }
static void fillComboBoxAxisType(QComboBox *box)
Ui::DialogMirrorByAxis * ui
quint32 getOriginPointId() const
DialogMirrorByAxis(const VContainer *data, const quint32 &toolId, QWidget *parent=nullptr)
virtual void ChosenObject(quint32 id, const SceneObject &type) Q_DECL_OVERRIDE
void setSourceObjects(const QVector< SourceItem > &value)
QString getSuffix() const
AxisType getAxisType() const
void setOriginPointId(quint32 value)
void setSuffix(const QString &value)
virtual void CheckState() Q_DECL_FINAL
CheckState enable, when all is correct, or disable, when something wrong, button ok.
QVector< SourceItem > getSourceObjects() const
void setAxisType(AxisType type)
virtual void ShowDialog(bool click) Q_DECL_OVERRIDE
virtual void SaveData() Q_DECL_OVERRIDE
SaveData Put dialog data in local variables.
virtual void ShowVisualization() Q_DECL_OVERRIDE
virtual void SelectedObject(bool selected, quint32 id, quint32 tool) 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
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 setAxisType(AxisType value)
virtual void RefreshGeometry() Q_DECL_OVERRIDE
void setOriginPointId(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)
AxisType
@ HorizontalAxis
#define qApp
Definition: vapplication.h:67