1 /************************************************************************
2  **
3  **  @file   vtoolcubicbezier.cpp
4  **  @author Roman Telezhynskyi <dismine(at)gmail.com>
5  **  @date   10 3, 2016
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) 2016 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 "vtoolcubicbezier.h"
30 
31 #include <QDomElement>
32 #include <QPen>
33 #include <QSharedPointer>
34 #include <QStaticStringData>
35 #include <QStringData>
36 #include <QStringDataPtr>
37 #include <Qt>
38 #include <new>
39 
40 #include "../../../dialogs/tools/dialogtool.h"
41 #include "../../../dialogs/tools/dialogcubicbezier.h"
42 #include "../../../visualization/visualization.h"
43 #include "../../../visualization/path/vistoolcubicbezier.h"
44 #include "../ifc/exception/vexception.h"
45 #include "../vgeometry/../ifc/ifcdef.h"
46 #include "../vgeometry/vabstractcurve.h"
47 #include "../vgeometry/vcubicbezier.h"
48 #include "../vgeometry/vgobject.h"
49 #include "../vgeometry/vpointf.h"
50 #include "../vmisc/vabstractapplication.h"
51 #include "../vpatterndb/vcontainer.h"
52 #include "../vwidgets/vmaingraphicsscene.h"
53 #include "../../vabstracttool.h"
54 #include "../vdrawtool.h"
55 #include "vabstractspline.h"
56 
57 const QString VToolCubicBezier::ToolType = QStringLiteral("cubicBezier");
58 
59 //---------------------------------------------------------------------------------------------------------------------
VToolCubicBezier(const VToolCubicBezierInitData & initData,QGraphicsItem * parent)60 VToolCubicBezier::VToolCubicBezier(const VToolCubicBezierInitData &initData, QGraphicsItem *parent)
61     :VAbstractSpline(initData.doc, initData.data, initData.id, initData.notes, parent)
62 {
63     sceneType = SceneObject::Spline;
64 
65     this->setFlag(QGraphicsItem::ItemIsFocusable, true);// For keyboard input focus
66 
67     ToolCreation(initData.typeCreation);
68 }
69 
70 //---------------------------------------------------------------------------------------------------------------------
setDialog()71 void VToolCubicBezier::setDialog()
72 {
73     SCASSERT(not m_dialog.isNull())
74     auto dialogTool = qobject_cast<DialogCubicBezier*>(m_dialog);
75     SCASSERT(dialogTool != nullptr)
76     const auto spl = VAbstractTool::data.GeometricObject<VCubicBezier>(m_id);
77     dialogTool->SetSpline(*spl);
78     dialogTool->SetNotes(m_notes);
79 }
80 
81 //---------------------------------------------------------------------------------------------------------------------
Create(const QPointer<DialogTool> & dialog,VMainGraphicsScene * scene,VAbstractPattern * doc,VContainer * data)82 VToolCubicBezier *VToolCubicBezier::Create(const QPointer<DialogTool> &dialog, VMainGraphicsScene *scene,
83                                            VAbstractPattern *doc, VContainer *data)
84 {
85     SCASSERT(not dialog.isNull())
86     const QPointer<DialogCubicBezier> dialogTool = qobject_cast<DialogCubicBezier *>(dialog);
87     SCASSERT(not dialogTool.isNull())
88 
89     VToolCubicBezierInitData initData;
90     initData.scene = scene;
91     initData.doc = doc;
92     initData.data = data;
93     initData.parse = Document::FullParse;
94     initData.typeCreation = Source::FromGui;
95     initData.spline = new VCubicBezier(dialogTool->GetSpline());
96     initData.notes = dialogTool->GetNotes();
97 
98     auto* spl = Create(initData);
99 
100     if (spl != nullptr)
101     {
102         spl->m_dialog = dialog;
103     }
104     return spl;
105 }
106 
107 //---------------------------------------------------------------------------------------------------------------------
Create(VToolCubicBezierInitData initData)108 VToolCubicBezier *VToolCubicBezier::Create(VToolCubicBezierInitData initData)
109 {
110     if (initData.typeCreation == Source::FromGui)
111     {
112         initData.id = initData.data->AddGObject(initData.spline);
113         initData.data->AddSpline(initData.data->GeometricObject<VAbstractBezier>(initData.id), initData.id);
114     }
115     else
116     {
117         initData.data->UpdateGObject(initData.id, initData.spline);
118         initData.data->AddSpline(initData.data->GeometricObject<VAbstractBezier>(initData.id), initData.id);
119         if (initData.parse != Document::FullParse)
120         {
121             initData.doc->UpdateToolData(initData.id, initData.data);
122         }
123     }
124 
125     if (initData.parse == Document::FullParse)
126     {
127         VAbstractTool::AddRecord(initData.id, Tool::CubicBezier, initData.doc);
128         auto* _spl = new VToolCubicBezier(initData);
129         initData.scene->addItem(_spl);
130         InitSplineToolConnections(initData.scene, _spl);
131         VAbstractPattern::AddTool(initData.id, _spl);
132         initData.doc->IncrementReferens(initData.spline->GetP1().getIdTool());
133         initData.doc->IncrementReferens(initData.spline->GetP1().getIdTool());
134         initData.doc->IncrementReferens(initData.spline->GetP1().getIdTool());
135         initData.doc->IncrementReferens(initData.spline->GetP4().getIdTool());
136         return _spl;
137     }
138     return nullptr;
139 }
140 
141 //---------------------------------------------------------------------------------------------------------------------
FirstPointName() const142 QString VToolCubicBezier::FirstPointName() const
143 {
144     auto spline = VAbstractTool::data.GeometricObject<VCubicBezier>(m_id);
145     return spline->GetP1().name();
146 }
147 
148 //---------------------------------------------------------------------------------------------------------------------
SecondPointName() const149 QString VToolCubicBezier::SecondPointName() const
150 {
151     auto spline = VAbstractTool::data.GeometricObject<VCubicBezier>(m_id);
152     return spline->GetP2().name();
153 }
154 
155 //---------------------------------------------------------------------------------------------------------------------
ThirdPointName() const156 QString VToolCubicBezier::ThirdPointName() const
157 {
158     auto spline = VAbstractTool::data.GeometricObject<VCubicBezier>(m_id);
159     return spline->GetP3().name();
160 }
161 
162 //---------------------------------------------------------------------------------------------------------------------
ForthPointName() const163 QString VToolCubicBezier::ForthPointName() const
164 {
165     auto spline = VAbstractTool::data.GeometricObject<VCubicBezier>(m_id);
166     return spline->GetP4().name();
167 }
168 
169 //---------------------------------------------------------------------------------------------------------------------
getSpline() const170 VCubicBezier VToolCubicBezier::getSpline() const
171 {
172     auto spline = VAbstractTool::data.GeometricObject<VCubicBezier>(m_id);
173     return *spline.data();
174 }
175 
176 //---------------------------------------------------------------------------------------------------------------------
setSpline(const VCubicBezier & spl)177 void VToolCubicBezier::setSpline(const VCubicBezier &spl)
178 {
179     QSharedPointer<VGObject> obj = VAbstractTool::data.GetGObject(m_id);
180     QSharedPointer<VCubicBezier> spline = qSharedPointerDynamicCast<VCubicBezier>(obj);
181     *spline.data() = spl;
182     SaveOption(obj);
183 }
184 
185 //---------------------------------------------------------------------------------------------------------------------
ShowVisualization(bool show)186 void VToolCubicBezier::ShowVisualization(bool show)
187 {
188     ShowToolVisualization<VisToolCubicBezier>(show);
189 }
190 
191 //---------------------------------------------------------------------------------------------------------------------
ShowContextMenu(QGraphicsSceneContextMenuEvent * event,quint32 id)192 void VToolCubicBezier::ShowContextMenu(QGraphicsSceneContextMenuEvent *event, quint32 id)
193 {
194     Q_UNUSED(id)
195     try
196     {
197         ContextMenu<DialogCubicBezier>(event);
198     }
199     catch(const VExceptionToolWasDeleted &e)
200     {
201         Q_UNUSED(e)
202         return;//Leave this method immediately!!!
203     }
204 }
205 
206 //---------------------------------------------------------------------------------------------------------------------
RemoveReferens()207 void VToolCubicBezier::RemoveReferens()
208 {
209     const auto spl = VAbstractTool::data.GeometricObject<VCubicBezier>(m_id);
210     doc->DecrementReferens(spl->GetP1().getIdTool());
211     doc->DecrementReferens(spl->GetP2().getIdTool());
212     doc->DecrementReferens(spl->GetP3().getIdTool());
213     doc->DecrementReferens(spl->GetP4().getIdTool());
214 }
215 
216 //---------------------------------------------------------------------------------------------------------------------
SaveDialog(QDomElement & domElement,QList<quint32> & oldDependencies,QList<quint32> & newDependencies)217 void VToolCubicBezier::SaveDialog(QDomElement &domElement, QList<quint32> &oldDependencies,
218                                   QList<quint32> &newDependencies)
219 {
220     SCASSERT(not m_dialog.isNull())
221     auto dialogTool = qobject_cast<DialogCubicBezier*>(m_dialog);
222     SCASSERT(dialogTool != nullptr)
223 
224     const auto oldSpl = VAbstractTool::data.GeometricObject<VCubicBezier>(m_id);
225     AddDependence(oldDependencies, oldSpl->GetP1().id());
226     AddDependence(oldDependencies, oldSpl->GetP2().id());
227     AddDependence(oldDependencies, oldSpl->GetP3().id());
228     AddDependence(oldDependencies, oldSpl->GetP4().id());
229 
230     const VCubicBezier spl = dialogTool->GetSpline();
231     AddDependence(newDependencies, spl.GetP1().id());
232     AddDependence(newDependencies, spl.GetP2().id());
233     AddDependence(newDependencies, spl.GetP3().id());
234     AddDependence(newDependencies, spl.GetP4().id());
235 
236     const QString notes = dialogTool->GetNotes();
237     doc->SetAttributeOrRemoveIf(domElement, AttrNotes, notes, notes.isEmpty());
238 
239     SetSplineAttributes(domElement, spl);
240 }
241 
242 //---------------------------------------------------------------------------------------------------------------------
SaveOptions(QDomElement & tag,QSharedPointer<VGObject> & obj)243 void VToolCubicBezier::SaveOptions(QDomElement &tag, QSharedPointer<VGObject> &obj)
244 {
245     VAbstractSpline::SaveOptions(tag, obj);
246 
247     auto spl = qSharedPointerDynamicCast<VCubicBezier>(obj);
248     SCASSERT(spl.isNull() == false)
249     SetSplineAttributes(tag, *spl);
250 }
251 
252 //---------------------------------------------------------------------------------------------------------------------
SetVisualization()253 void VToolCubicBezier::SetVisualization()
254 {
255     if (not vis.isNull())
256     {
257         auto visual = qobject_cast<VisToolCubicBezier *>(vis);
258         SCASSERT(visual != nullptr)
259 
260         const QSharedPointer<VCubicBezier> spl = VAbstractTool::data.GeometricObject<VCubicBezier>(m_id);
261         visual->setObject1Id(spl->GetP1().id());
262         visual->setObject2Id(spl->GetP2().id());
263         visual->setObject3Id(spl->GetP3().id());
264         visual->setObject4Id(spl->GetP4().id());
265         visual->setLineStyle(LineStyleToPenStyle(spl->GetPenStyle()));
266         visual->setApproximationScale(spl->GetApproximationScale());
267         visual->SetMode(Mode::Show);
268         visual->RefreshGeometry();
269     }
270 }
271 
272 //---------------------------------------------------------------------------------------------------------------------
RefreshGeometry()273 void VToolCubicBezier::RefreshGeometry()
274 {
275     const QSharedPointer<VCubicBezier> spl = VAbstractTool::data.GeometricObject<VCubicBezier>(m_id);
276     this->setPath(spl->GetPath());
277 
278     SetVisualization();
279 }
280 
281 //---------------------------------------------------------------------------------------------------------------------
SetSplineAttributes(QDomElement & domElement,const VCubicBezier & spl)282 void VToolCubicBezier::SetSplineAttributes(QDomElement &domElement, const VCubicBezier &spl)
283 {
284     SCASSERT(doc != nullptr)
285 
286     doc->SetAttribute(domElement, AttrType,     ToolType);
287     doc->SetAttribute(domElement, AttrPoint1,   spl.GetP1().id());
288     doc->SetAttribute(domElement, AttrPoint2,   spl.GetP2().id());
289     doc->SetAttribute(domElement, AttrPoint3,   spl.GetP3().id());
290     doc->SetAttribute(domElement, AttrPoint4,   spl.GetP4().id());
291     doc->SetAttribute(domElement, AttrColor,    spl.GetColor());
292     doc->SetAttribute(domElement, AttrPenStyle, spl.GetPenStyle());
293     doc->SetAttribute(domElement, AttrAScale,   spl.GetApproximationScale());
294     doc->SetAttributeOrRemoveIf(domElement, AttrDuplicate, spl.GetDuplicate(), spl.GetDuplicate() <= 0);
295     doc->SetAttributeOrRemoveIf(domElement, AttrAlias, spl.GetAliasSuffix(), spl.GetAliasSuffix().isEmpty());
296 }
297