1 /************************************************************************
2  **
3  **  @file   vtoolplacelabel.cpp
4  **  @author Roman Telezhynskyi <dismine(at)gmail.com>
5  **  @date   15 10, 2017
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) 2017 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 "vtoolplacelabel.h"
30 #include "../../dialogs/tools/piece/dialogplacelabel.h"
31 #include "../../undocommands/savepieceoptions.h"
32 #include "../vtoolseamallowance.h"
33 #include "../vgeometry/vpointf.h"
34 #include "../vgeometry/vplacelabelitem.h"
35 
36 const QString VToolPlaceLabel::ToolType = QStringLiteral("placeLabel");
37 
38 //---------------------------------------------------------------------------------------------------------------------
Create(const QPointer<DialogTool> & dialog,VAbstractPattern * doc,VContainer * data)39 VToolPlaceLabel *VToolPlaceLabel::Create(const QPointer<DialogTool> &dialog, VAbstractPattern *doc, VContainer *data)
40 {
41     SCASSERT(not dialog.isNull());
42     const QPointer<DialogPlaceLabel> dialogTool = qobject_cast<DialogPlaceLabel *>(dialog);
43     SCASSERT(not dialogTool.isNull())
44 
45     VToolPlaceLabelInitData initData;
46     initData.width = dialogTool->GetWidth();
47     initData.height = dialogTool->GetHeight();
48     initData.angle = dialogTool->GetAngle();
49     initData.visibilityTrigger = dialogTool->GetFormulaVisible();
50     initData.type = dialogTool->GetLabelType();
51     initData.centerPoint = dialogTool->GetCenterPoint();
52     initData.idObject = dialogTool->GetPieceId();
53     initData.doc = doc;
54     initData.data = data;
55     initData.parse = Document::FullParse;
56     initData.typeCreation = Source::FromGui;
57 
58     return Create(initData);
59 }
60 
61 //---------------------------------------------------------------------------------------------------------------------
Create(VToolPlaceLabelInitData & initData)62 VToolPlaceLabel *VToolPlaceLabel::Create(VToolPlaceLabelInitData &initData)
63 {
64     const qreal w =
65             qAbs(VAbstractValApplication::VApp()->toPixel(CheckFormula(initData.id, initData.width, initData.data)));
66     const qreal h =
67             qAbs(VAbstractValApplication::VApp()->toPixel(CheckFormula(initData.id, initData.height, initData.data)));
68     const qreal a = CheckFormula(initData.id, initData.angle, initData.data);
69     const qreal v = CheckFormula(initData.id, initData.visibilityTrigger, initData.data);
70 
71     QSharedPointer<VPlaceLabelItem> node(new VPlaceLabelItem());
72     node->SetWidth(w, initData.width);
73     node->SetHeight(h, initData.height);
74     node->SetAngle(a, initData.angle);
75     node->SetVisibilityTrigger(v, initData.visibilityTrigger);
76     node->SetLabelType(initData.type);
77     node->SetCenterPoint(initData.centerPoint);
78 
79     if (initData.typeCreation == Source::FromGui)
80     {
81         //We can't use exist object. Need create new.
82         auto point = initData.data->GeometricObject<VPointF>(initData.centerPoint);
83 
84         node->setName(point->name());
85         node->setX(point->x());
86         node->setY(point->y());
87         node->setMx(point->mx());
88         node->setMy(point->my());
89 
90         initData.id = initData.data->AddGObject(node);
91     }
92     else
93     {
94         QSharedPointer<VPointF> point;
95         try
96         {
97             point = initData.data->GeometricObject<VPointF>(initData.centerPoint);
98         }
99         catch (const VExceptionBadId &e)
100         { // Possible case. Parent was deleted, but the node object is still here.
101             Q_UNUSED(e)
102             initData.data->UpdateId(initData.id);
103             return nullptr;// Just ignore
104         }
105         node->setName(point->name());
106         node->setX(point->x());
107         node->setY(point->y());
108         node->setMx(point->mx());
109         node->setMy(point->my());
110 
111         if (initData.idTool != NULL_ID)
112         {
113             QSharedPointer<VPlaceLabelItem> label = qSharedPointerDynamicCast<VPlaceLabelItem>(point);
114             SCASSERT(label.isNull() == false)
115 
116             node->SetCorrectionAngle(label->GetCorrectionAngle());
117         }
118 
119         initData.data->UpdateGObject(initData.id, node);
120         if (initData.parse != Document::FullParse)
121         {
122             initData.doc->UpdateToolData(initData.id, initData.data);
123         }
124     }
125     VAbstractTool::AddRecord(initData.id, Tool::PlaceLabel, initData.doc);
126     VToolPlaceLabel *point = nullptr;
127     if (initData.parse == Document::FullParse)
128     {
129         point = new VToolPlaceLabel(initData);
130 
131         VAbstractPattern::AddTool(initData.id, point);
132         if (initData.idTool != NULL_ID)
133         {
134             //Some nodes we don't show on scene. Tool that creates this nodes must free memory.
135             VDataTool *tool = VAbstractPattern::getTool(initData.idTool);
136             SCASSERT(tool != nullptr)
137             point->setParent(tool);// Adopted by a tool
138         }
139         else
140         {
141             // Help to delete the node before each FullParse
142             initData.doc->AddToolOnRemove(point);
143         }
144     }
145     else
146     {
147         initData.doc->UpdateToolData(initData.id, initData.data);
148     }
149     return point;
150 }
151 
152 //---------------------------------------------------------------------------------------------------------------------
getTagName() const153 QString VToolPlaceLabel::getTagName() const
154 {
155     return VAbstractPattern::TagPoint;
156 }
157 
158 //---------------------------------------------------------------------------------------------------------------------
AddAttributes(VAbstractPattern * doc,QDomElement & domElement,quint32 id,const VPlaceLabelItem & label)159 void VToolPlaceLabel::AddAttributes(VAbstractPattern *doc, QDomElement &domElement, quint32 id,
160                                     const VPlaceLabelItem &label)
161 {
162     doc->SetAttribute(domElement, VDomDocument::AttrId, id);
163     doc->SetAttribute(domElement, AttrType, ToolType);
164     doc->SetAttribute(domElement, AttrIdObject, label.GetCenterPoint());
165     doc->SetAttribute(domElement, AttrWidth, label.GetWidthFormula());
166     doc->SetAttribute(domElement, AttrHeight, label.GetHeightFormula());
167     doc->SetAttribute(domElement, AttrAngle, label.GetAngleFormula());
168     doc->SetAttribute(domElement, VAbstractPattern::AttrVisible, label.GetVisibilityTrigger());
169     doc->SetAttribute(domElement, AttrPlaceLabelType, static_cast<int>(label.GetLabelType()));
170 }
171 
172 //---------------------------------------------------------------------------------------------------------------------
AllowHover(bool enabled)173 void VToolPlaceLabel::AllowHover(bool enabled)
174 {
175     Q_UNUSED(enabled)
176     // do nothing
177 }
178 
179 //---------------------------------------------------------------------------------------------------------------------
AllowSelecting(bool enabled)180 void VToolPlaceLabel::AllowSelecting(bool enabled)
181 {
182     Q_UNUSED(enabled)
183     // do nothing
184 }
185 
186 //---------------------------------------------------------------------------------------------------------------------
AddToFile()187 void VToolPlaceLabel::AddToFile()
188 {
189     auto label = VAbstractTool::data.GeometricObject<VPlaceLabelItem>(m_id);
190 
191     QDomElement domElement = doc->createElement(getTagName());
192 
193     AddAttributes(doc, domElement, m_id, *label);
194     if (idTool != NULL_ID)
195     {
196         doc->SetAttribute(domElement, AttrIdTool, idTool);
197     }
198 
199     AddToModeling(domElement);
200 
201     if (m_pieceId > NULL_ID)
202     {
203         const VPiece oldDet = VAbstractTool::data.GetPiece(m_pieceId);
204         VPiece newDet = oldDet;
205 
206         newDet.GetPlaceLabels().append(m_id);
207         incrementReferens(); // Manually increment reference since in this case a piece tool will not do this for us
208         VAbstractApplication::VApp()->getUndoStack()->push(new SavePieceOptions(oldDet, newDet, doc, m_pieceId));
209     }
210 }
211 
212 //---------------------------------------------------------------------------------------------------------------------
VToolPlaceLabel(const VToolPlaceLabelInitData & initData,QObject * qoParent)213 VToolPlaceLabel::VToolPlaceLabel(const VToolPlaceLabelInitData &initData, QObject *qoParent)
214     : VAbstractNode(initData.doc, initData.data, initData.id, initData.centerPoint, initData.drawName,
215                     initData.idTool, qoParent),
216       m_pieceId(initData.idObject)
217 {
218     ToolCreation(initData.typeCreation);
219 }
220