1 /************************************************************************
2 **
3 ** @file vtoolarc.cpp
4 ** @author Roman Telezhynskyi <dismine(at)gmail.com>
5 ** @date November 15, 2013
6 **
7 ** @brief
8 ** @copyright
9 ** This source code is part of the Valentina project, a pattern making
10 ** program, whose allow create and modeling patterns of clothing.
11 ** Copyright (C) 2013-2015 Valentina project
12 ** <https://gitlab.com/smart-pattern/valentina> All Rights Reserved.
13 **
14 ** Valentina is free software: you can redistribute it and/or modify
15 ** it under the terms of the GNU General Public License as published by
16 ** the Free Software Foundation, either version 3 of the License, or
17 ** (at your option) any later version.
18 **
19 ** Valentina is distributed in the hope that it will be useful,
20 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
21 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 ** GNU General Public License for more details.
23 **
24 ** You should have received a copy of the GNU General Public License
25 ** along with Valentina. If not, see <http://www.gnu.org/licenses/>.
26 **
27 *************************************************************************/
28
29 #include "vtoolarc.h"
30
31 #include <QPen>
32 #include <QSharedPointer>
33 #include <QStaticStringData>
34 #include <QStringData>
35 #include <QStringDataPtr>
36 #include <Qt>
37 #include <new>
38
39 #include "../../../dialogs/tools/dialogtool.h"
40 #include "../../../dialogs/tools/dialogarc.h"
41 #include "../../../visualization/path/vistoolarc.h"
42 #include "../../../visualization/visualization.h"
43 #include "../ifc/exception/vexception.h"
44 #include "../ifc/xml/vdomdocument.h"
45 #include "../ifc/ifcdef.h"
46 #include "../vgeometry/varc.h"
47 #include "../vgeometry/vgobject.h"
48 #include "../vgeometry/vpointf.h"
49 #include "../vmisc/vabstractapplication.h"
50 #include "../vmisc/vcommonsettings.h"
51 #include "../vpatterndb/vcontainer.h"
52 #include "../vpatterndb/vformula.h"
53 #include "../vpatterndb/vtranslatevars.h"
54 #include "../vwidgets/vmaingraphicsscene.h"
55 #include "../../vabstracttool.h"
56 #include "../vdrawtool.h"
57 #include "vabstractspline.h"
58
59 const QString VToolArc::ToolType = QStringLiteral("simple");
60
61 //---------------------------------------------------------------------------------------------------------------------
62 /**
63 * @brief VToolArc constuctor.
64 * @param initData init data
65 */
VToolArc(const VToolArcInitData & initData,QGraphicsItem * parent)66 VToolArc::VToolArc(const VToolArcInitData &initData, QGraphicsItem *parent)
67 : VToolAbstractArc(initData.doc, initData.data, initData.id, initData.notes, parent)
68 {
69 sceneType = SceneObject::Arc;
70
71 this->setFlag(QGraphicsItem::ItemIsFocusable, true);// For keyboard input focus
72
73 ToolCreation(initData.typeCreation);
74 }
75
76 //---------------------------------------------------------------------------------------------------------------------
77 /**
78 * @brief setDialog set dialog when user want change tool option.
79 */
setDialog()80 void VToolArc::setDialog()
81 {
82 SCASSERT(not m_dialog.isNull())
83 const QPointer<DialogArc> dialogTool = qobject_cast<DialogArc *>(m_dialog);
84 SCASSERT(not dialogTool.isNull())
85 const QSharedPointer<VArc> arc = VAbstractTool::data.GeometricObject<VArc>(m_id);
86 dialogTool->SetCenter(arc->GetCenter().id());
87 dialogTool->SetF1(arc->GetFormulaF1());
88 dialogTool->SetF2(arc->GetFormulaF2());
89 dialogTool->SetRadius(arc->GetFormulaRadius());
90 dialogTool->SetColor(arc->GetColor());
91 dialogTool->SetPenStyle(arc->GetPenStyle());
92 dialogTool->SetApproximationScale(arc->GetApproximationScale());
93 dialogTool->SetNotes(m_notes);
94 dialogTool->SetAliasSuffix(arc->GetAliasSuffix());
95 }
96
97 //---------------------------------------------------------------------------------------------------------------------
98 /**
99 * @brief Create help create tool
100 * @param dialog dialog options.
101 * @param scene pointer to scene.
102 * @param doc dom document container
103 * @param data container with variables
104 */
Create(const QPointer<DialogTool> & dialog,VMainGraphicsScene * scene,VAbstractPattern * doc,VContainer * data)105 VToolArc* VToolArc::Create(const QPointer<DialogTool> &dialog, VMainGraphicsScene *scene, VAbstractPattern *doc,
106 VContainer *data)
107 {
108 SCASSERT(not dialog.isNull())
109 const QPointer<DialogArc> dialogTool = qobject_cast<DialogArc *>(dialog);
110 SCASSERT(not dialogTool.isNull())
111
112 VToolArcInitData initData;
113 initData.center = dialogTool->GetCenter();
114 initData.radius = dialogTool->GetRadius();
115 initData.f1 = dialogTool->GetF1();
116 initData.f2 = dialogTool->GetF2();
117 initData.color = dialogTool->GetColor();
118 initData.penStyle = dialogTool->GetPenStyle();
119 initData.scene = scene;
120 initData.doc = doc;
121 initData.data = data;
122 initData.parse = Document::FullParse;
123 initData.typeCreation = Source::FromGui;
124 initData.approximationScale = dialogTool->GetApproximationScale();
125 initData.notes = dialogTool->GetNotes();
126 initData.aliasSuffix = dialogTool->GetAliasSuffix();
127
128 VToolArc* point = Create(initData);
129 if (point != nullptr)
130 {
131 point->m_dialog = dialog;
132 }
133 return point;
134 }
135
136 //---------------------------------------------------------------------------------------------------------------------
137 /**
138 * @brief Create help create tool form GUI.
139 * @param initData init data.
140 */
Create(VToolArcInitData & initData)141 VToolArc* VToolArc::Create(VToolArcInitData &initData)
142 {
143 qreal calcRadius = 0, calcF1 = 0, calcF2 = 0;
144
145 calcRadius = VAbstractValApplication::VApp()->toPixel(CheckFormula(initData.id, initData.radius, initData.data));
146
147 calcF1 = CheckFormula(initData.id, initData.f1, initData.data);
148 calcF2 = CheckFormula(initData.id, initData.f2, initData.data);
149
150 const VPointF c = *initData.data->GeometricObject<VPointF>(initData.center);
151 VArc *arc = new VArc(c, calcRadius, initData.radius, calcF1, initData.f1, calcF2, initData.f2 );
152 arc->SetColor(initData.color);
153 arc->SetPenStyle(initData.penStyle);
154 arc->SetApproximationScale(initData.approximationScale);
155 arc->SetAliasSuffix(initData.aliasSuffix);
156
157 if (initData.typeCreation == Source::FromGui)
158 {
159 initData.id = initData.data->AddGObject(arc);
160 initData.data->AddArc(initData.data->GeometricObject<VArc>(initData.id), initData.id);
161 }
162 else
163 {
164 initData.data->UpdateGObject(initData.id, arc);
165 initData.data->AddArc(initData.data->GeometricObject<VArc>(initData.id), initData.id);
166 if (initData.parse != Document::FullParse)
167 {
168 initData.doc->UpdateToolData(initData.id, initData.data);
169 }
170 }
171
172 if (initData.parse == Document::FullParse)
173 {
174 VAbstractTool::AddRecord(initData.id, Tool::Arc, initData.doc);
175 VToolArc *toolArc = new VToolArc(initData);
176 initData.scene->addItem(toolArc);
177 InitArcToolConnections(initData.scene, toolArc);
178 VAbstractPattern::AddTool(initData.id, toolArc);
179 initData.doc->IncrementReferens(c.getIdTool());
180 return toolArc;
181 }
182 return nullptr;
183 }
184
185 //---------------------------------------------------------------------------------------------------------------------
getTagName() const186 QString VToolArc::getTagName() const
187 {
188 return VAbstractPattern::TagArc;
189 }
190
191 //---------------------------------------------------------------------------------------------------------------------
GetFormulaRadius() const192 VFormula VToolArc::GetFormulaRadius() const
193 {
194 QSharedPointer<VArc> arc = VAbstractTool::data.GeometricObject<VArc>(m_id);
195 SCASSERT(arc.isNull() == false)
196
197 VFormula radius(arc->GetFormulaRadius(), getData());
198 radius.setCheckZero(true);
199 radius.setToolId(m_id);
200 radius.setPostfix(UnitsToStr(VAbstractValApplication::VApp()->patternUnits()));
201 radius.Eval();
202 return radius;
203 }
204
205 //---------------------------------------------------------------------------------------------------------------------
SetFormulaRadius(const VFormula & value)206 void VToolArc::SetFormulaRadius(const VFormula &value)
207 {
208 if (value.error() == false)
209 {
210 if (value.getDoubleValue() > 0)// Formula don't check this, but radius can't be 0 or negative
211 {
212 QSharedPointer<VGObject> obj = VAbstractTool::data.GetGObject(m_id);
213 QSharedPointer<VArc> arc = qSharedPointerDynamicCast<VArc>(obj);
214 arc->SetFormulaRadius(value.GetFormula(FormulaType::FromUser), value.getDoubleValue());
215 SaveOption(obj);
216 }
217 }
218 }
219
220 //---------------------------------------------------------------------------------------------------------------------
GetFormulaF1() const221 VFormula VToolArc::GetFormulaF1() const
222 {
223 QSharedPointer<VArc> arc = VAbstractTool::data.GeometricObject<VArc>(m_id);
224 SCASSERT(arc.isNull() == false)
225
226 VFormula f1(arc->GetFormulaF1(), getData());
227 f1.setCheckZero(false);
228 f1.setToolId(m_id);
229 f1.setPostfix(degreeSymbol);
230 f1.Eval();
231 return f1;
232 }
233
234 //---------------------------------------------------------------------------------------------------------------------
SetFormulaF1(const VFormula & value)235 void VToolArc::SetFormulaF1(const VFormula &value)
236 {
237 if (value.error() == false)
238 {
239 QSharedPointer<VGObject> obj = VAbstractTool::data.GetGObject(m_id);
240 QSharedPointer<VArc> arc = qSharedPointerDynamicCast<VArc>(obj);
241
242 arc->SetFormulaF1(value.GetFormula(FormulaType::FromUser), value.getDoubleValue());
243 SaveOption(obj);
244 }
245 }
246
247 //---------------------------------------------------------------------------------------------------------------------
GetFormulaF2() const248 VFormula VToolArc::GetFormulaF2() const
249 {
250 QSharedPointer<VArc> arc = VAbstractTool::data.GeometricObject<VArc>(m_id);
251 SCASSERT(arc.isNull() == false)
252
253 VFormula f2(arc->GetFormulaF2(), getData());
254 f2.setCheckZero(false);
255 f2.setToolId(m_id);
256 f2.setPostfix(degreeSymbol);
257 f2.Eval();
258 return f2;
259 }
260
261 //---------------------------------------------------------------------------------------------------------------------
SetFormulaF2(const VFormula & value)262 void VToolArc::SetFormulaF2(const VFormula &value)
263 {
264 if (value.error() == false)
265 {
266 QSharedPointer<VGObject> obj = VAbstractTool::data.GetGObject(m_id);
267 QSharedPointer<VArc> arc = qSharedPointerDynamicCast<VArc>(obj);
268 arc->SetFormulaF2(value.GetFormula(FormulaType::FromUser), value.getDoubleValue());
269 SaveOption(obj);
270 }
271 }
272
273 //---------------------------------------------------------------------------------------------------------------------
GetApproximationScale() const274 qreal VToolArc::GetApproximationScale() const
275 {
276 QSharedPointer<VArc> arc = VAbstractTool::data.GeometricObject<VArc>(m_id);
277 SCASSERT(arc.isNull() == false)
278
279 return arc->GetApproximationScale();
280 }
281
282 //---------------------------------------------------------------------------------------------------------------------
SetApproximationScale(qreal value)283 void VToolArc::SetApproximationScale(qreal value)
284 {
285 QSharedPointer<VGObject> obj = VAbstractTool::data.GetGObject(m_id);
286 QSharedPointer<VArc> arc = qSharedPointerDynamicCast<VArc>(obj);
287 arc->SetApproximationScale(value);
288 SaveOption(obj);
289 }
290
291 //---------------------------------------------------------------------------------------------------------------------
ShowVisualization(bool show)292 void VToolArc::ShowVisualization(bool show)
293 {
294 ShowToolVisualization<VisToolArc>(show);
295 }
296
297 //---------------------------------------------------------------------------------------------------------------------
ShowContextMenu(QGraphicsSceneContextMenuEvent * event,quint32 id)298 void VToolArc::ShowContextMenu(QGraphicsSceneContextMenuEvent *event, quint32 id)
299 {
300 Q_UNUSED(id)
301 try
302 {
303 ContextMenu<DialogArc>(event);
304 }
305 catch(const VExceptionToolWasDeleted &e)
306 {
307 Q_UNUSED(e)
308 return;//Leave this method immediately!!!
309 }
310 }
311
312 //---------------------------------------------------------------------------------------------------------------------
313 /**
314 * @brief RemoveReferens decrement value of reference.
315 */
RemoveReferens()316 void VToolArc::RemoveReferens()
317 {
318 const auto arc = VAbstractTool::data.GeometricObject<VArc>(m_id);
319 doc->DecrementReferens(arc->GetCenter().getIdTool());
320 }
321
322 //---------------------------------------------------------------------------------------------------------------------
323 /**
324 * @brief SaveDialog save options into file after change in dialog.
325 */
SaveDialog(QDomElement & domElement,QList<quint32> & oldDependencies,QList<quint32> & newDependencies)326 void VToolArc::SaveDialog(QDomElement &domElement, QList<quint32> &oldDependencies, QList<quint32> &newDependencies)
327 {
328 SCASSERT(not m_dialog.isNull())
329 QPointer<DialogArc> dialogTool = qobject_cast<DialogArc *>(m_dialog);
330 SCASSERT(not dialogTool.isNull())
331
332 QSharedPointer<VArc> arc = VAbstractTool::data.GeometricObject<VArc>(m_id);
333 SCASSERT(arc.isNull() == false)
334 AddDependence(oldDependencies, arc->GetCenter().id());
335 AddDependence(newDependencies, dialogTool->GetCenter());
336
337 doc->SetAttribute(domElement, AttrCenter, QString().setNum(dialogTool->GetCenter()));
338 doc->SetAttribute(domElement, AttrRadius, dialogTool->GetRadius());
339 doc->SetAttribute(domElement, AttrAngle1, dialogTool->GetF1());
340 doc->SetAttribute(domElement, AttrAngle2, dialogTool->GetF2());
341 doc->SetAttribute(domElement, AttrColor, dialogTool->GetColor());
342 doc->SetAttribute(domElement, AttrPenStyle, dialogTool->GetPenStyle());
343 doc->SetAttribute(domElement, AttrAScale, dialogTool->GetApproximationScale());
344 doc->SetAttributeOrRemoveIf(domElement, AttrAlias, dialogTool->GetAliasSuffix(),
345 dialogTool->GetAliasSuffix().isEmpty());
346
347 const QString notes = dialogTool->GetNotes();
348 doc->SetAttributeOrRemoveIf(domElement, AttrNotes, notes, notes.isEmpty());
349 }
350
351 //---------------------------------------------------------------------------------------------------------------------
SaveOptions(QDomElement & tag,QSharedPointer<VGObject> & obj)352 void VToolArc::SaveOptions(QDomElement &tag, QSharedPointer<VGObject> &obj)
353 {
354 VAbstractSpline::SaveOptions(tag, obj);
355
356 QSharedPointer<VArc> arc = qSharedPointerDynamicCast<VArc>(obj);
357 SCASSERT(arc.isNull() == false)
358
359 doc->SetAttribute(tag, AttrType, ToolType);
360 doc->SetAttribute(tag, AttrCenter, arc->GetCenter().id());
361 doc->SetAttribute(tag, AttrRadius, arc->GetFormulaRadius());
362 doc->SetAttribute(tag, AttrAngle1, arc->GetFormulaF1());
363 doc->SetAttribute(tag, AttrAngle2, arc->GetFormulaF2());
364 }
365
366 //---------------------------------------------------------------------------------------------------------------------
SetVisualization()367 void VToolArc::SetVisualization()
368 {
369 if (not vis.isNull())
370 {
371 const QSharedPointer<VArc> arc = VAbstractTool::data.GeometricObject<VArc>(m_id);
372 VisToolArc *visual = qobject_cast<VisToolArc *>(vis);
373 SCASSERT(visual != nullptr)
374
375 const VTranslateVars *trVars = VAbstractApplication::VApp()->TrVars();
376 visual->setObject1Id(arc->GetCenter().id());
377 visual->setRadius(trVars->FormulaToUser(
378 arc->GetFormulaRadius(), VAbstractApplication::VApp()->Settings()->GetOsSeparator()));
379 visual->setF1(trVars->FormulaToUser(
380 arc->GetFormulaF1(), VAbstractApplication::VApp()->Settings()->GetOsSeparator()));
381 visual->setF2(trVars->FormulaToUser(
382 arc->GetFormulaF2(), VAbstractApplication::VApp()->Settings()->GetOsSeparator()));
383 visual->setLineStyle(LineStyleToPenStyle(arc->GetPenStyle()));
384 visual->setApproximationScale(arc->GetApproximationScale());
385 visual->RefreshGeometry();
386 }
387 }
388
389 //---------------------------------------------------------------------------------------------------------------------
MakeToolTip() const390 QString VToolArc::MakeToolTip() const
391 {
392 const QSharedPointer<VArc> arc = VAbstractTool::data.GeometricObject<VArc>(m_id);
393
394 const QString toolTip = QString("<table>"
395 "<tr> <td><b>%10:</b> %11</td> </tr>"
396 "<tr> <td><b>%1:</b> %2 %3</td> </tr>"
397 "<tr> <td><b>%4:</b> %5 %3</td> </tr>"
398 "<tr> <td><b>%6:</b> %7°</td> </tr>"
399 "<tr> <td><b>%8:</b> %9°</td> </tr>"
400 "</table>")
401 .arg(tr("Length"))
402 .arg(VAbstractValApplication::VApp()->fromPixel(arc->GetLength()))
403 .arg(UnitsToStr(VAbstractValApplication::VApp()->patternUnits(), true), tr("Radius"))
404 .arg(VAbstractValApplication::VApp()->fromPixel(arc->GetRadius()))
405 .arg(tr("Start angle"))
406 .arg(arc->GetStartAngle())
407 .arg(tr("End angle"))
408 .arg(arc->GetEndAngle())
409 .arg(tr("Label"), arc->ObjectName());
410 return toolTip;
411 }
412