1 /************************************************************************
2  **
3  **  @file   vtooldoublepoint.cpp
4  **  @author Roman Telezhynskyi <dismine(at)gmail.com>
5  **  @date   20 6, 2015
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) 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 "vtooldoublepoint.h"
30 
31 #include <QColor>
32 #include <QDomElement>
33 #include <QKeyEvent>
34 #include <QPoint>
35 #include <QSharedPointer>
36 #include <QUndoStack>
37 #include <Qt>
38 #include <new>
39 
40 #include "../../../../undocommands/label/movedoublelabel.h"
41 #include "../../../../undocommands/label/showdoublelabel.h"
42 #include "../ifc/exception/vexception.h"
43 #include "../ifc/exception/vexceptionbadid.h"
44 #include "../ifc/xml/vabstractpattern.h"
45 #include "../vgeometry/vgobject.h"
46 #include "../vgeometry/vpointf.h"
47 #include "../vmisc/vabstractapplication.h"
48 #include "../vpatterndb/vcontainer.h"
49 #include "../vwidgets/../ifc/ifcdef.h"
50 #include "../vwidgets/vsimplepoint.h"
51 #include "../../../vabstracttool.h"
52 #include "../../../vdatatool.h"
53 #include "../../vdrawtool.h"
54 #include "../vabstractpoint.h"
55 
56 //---------------------------------------------------------------------------------------------------------------------
VToolDoublePoint(VAbstractPattern * doc,VContainer * data,quint32 id,quint32 p1id,quint32 p2id,const QString & notes,QGraphicsItem * parent)57 VToolDoublePoint::VToolDoublePoint(VAbstractPattern *doc, VContainer *data, quint32 id, quint32 p1id, quint32 p2id,
58                                    const QString &notes, QGraphicsItem *parent)
59     :VAbstractPoint(doc, data, id, notes),
60       QGraphicsPathItem(parent),
61       firstPoint(nullptr),
62       secondPoint(nullptr),
63       p1id(p1id),
64       p2id(p2id)
65 {
66     firstPoint = new VSimplePoint(p1id, QColor(Qt::black));
67     firstPoint->setParentItem(this);
68     firstPoint->setToolTip(ComplexToolTip(p1id));
69     connect(firstPoint, &VSimplePoint::Choosed, this, &VToolDoublePoint::Point1Choosed);
70     connect(firstPoint, &VSimplePoint::Selected, this, &VToolDoublePoint::Point1Selected);
71     connect(firstPoint, &VSimplePoint::ShowContextMenu, this, &VToolDoublePoint::ShowContextMenu);
72     connect(firstPoint, &VSimplePoint::Delete, this, &VToolDoublePoint::DeleteFromLabel);
73     connect(firstPoint, &VSimplePoint::NameChangedPosition, this, &VToolDoublePoint::Label1ChangePosition);
74     firstPoint->RefreshPointGeometry(*VAbstractTool::data.GeometricObject<VPointF>(p1id));
75 
76     secondPoint = new VSimplePoint(p2id, QColor(Qt::black));
77     secondPoint->setParentItem(this);
78     secondPoint->setToolTip(ComplexToolTip(p2id));
79     connect(secondPoint, &VSimplePoint::Choosed, this, &VToolDoublePoint::Point2Choosed);
80     connect(secondPoint, &VSimplePoint::Selected, this, &VToolDoublePoint::Point2Selected);
81     connect(secondPoint, &VSimplePoint::ShowContextMenu, this, &VToolDoublePoint::ShowContextMenu);
82     connect(secondPoint, &VSimplePoint::Delete, this, &VToolDoublePoint::DeleteFromLabel);
83     connect(secondPoint, &VSimplePoint::NameChangedPosition, this, &VToolDoublePoint::Label2ChangePosition);
84     secondPoint->RefreshPointGeometry(*VAbstractTool::data.GeometricObject<VPointF>(p2id));
85 }
86 
87 //---------------------------------------------------------------------------------------------------------------------
nameP1() const88 QString VToolDoublePoint::nameP1() const
89 {
90     return ObjectName<VPointF>(p1id);
91 }
92 
93 //---------------------------------------------------------------------------------------------------------------------
setNameP1(const QString & name)94 void VToolDoublePoint::setNameP1(const QString &name)
95 {
96     SetPointName(p1id, name);
97 }
98 
99 //---------------------------------------------------------------------------------------------------------------------
nameP2() const100 QString VToolDoublePoint::nameP2() const
101 {
102     return ObjectName<VPointF>(p2id);
103 }
104 
105 //---------------------------------------------------------------------------------------------------------------------
setNameP2(const QString & name)106 void VToolDoublePoint::setNameP2(const QString &name)
107 {
108     SetPointName(p2id, name);
109 }
110 
111 //---------------------------------------------------------------------------------------------------------------------
GroupVisibility(quint32 object,bool visible)112 void VToolDoublePoint::GroupVisibility(quint32 object, bool visible)
113 {
114     if (object == p1id)
115     {
116         firstPoint->setVisible(visible);
117     }
118     else if (object == p2id)
119     {
120         secondPoint->setVisible(visible);
121     }
122 }
123 
124 //---------------------------------------------------------------------------------------------------------------------
IsLabelVisible(quint32 id) const125 bool VToolDoublePoint::IsLabelVisible(quint32 id) const
126 {
127     if (p1id == id)
128     {
129         return VAbstractTool::data.GeometricObject<VPointF>(p1id)->IsShowLabel();
130     }
131     else if (p2id == id)
132     {
133         return VAbstractTool::data.GeometricObject<VPointF>(p2id)->IsShowLabel();
134     }
135     else
136     {
137         return false;
138     }
139 }
140 
141 //---------------------------------------------------------------------------------------------------------------------
SetLabelVisible(quint32 id,bool visible)142 void VToolDoublePoint::SetLabelVisible(quint32 id, bool visible)
143 {
144     if (p1id == id)
145     {
146         const QSharedPointer<VPointF> point = VAbstractTool::data.GeometricObject<VPointF>(p1id);
147         point->SetShowLabel(visible);
148         firstPoint->RefreshPointGeometry(*point);
149         if (QGraphicsScene *sc = firstPoint->scene())
150         {
151             VMainGraphicsView::NewSceneRect(sc, VAbstractValApplication::VApp()->getSceneView(), firstPoint);
152         }
153     }
154     else if (p2id == id)
155     {
156         const QSharedPointer<VPointF> point = VAbstractTool::data.GeometricObject<VPointF>(p2id);
157         point->SetShowLabel(visible);
158         secondPoint->RefreshPointGeometry(*point);
159         if (QGraphicsScene *sc = secondPoint->scene())
160         {
161             VMainGraphicsView::NewSceneRect(sc, VAbstractValApplication::VApp()->getSceneView(), secondPoint);
162         }
163     }
164 }
165 
166 //---------------------------------------------------------------------------------------------------------------------
Label1ChangePosition(const QPointF & pos)167 void VToolDoublePoint::Label1ChangePosition(const QPointF &pos)
168 {
169     UpdateNamePosition(p1id, pos - firstPoint->pos());
170 }
171 
172 //---------------------------------------------------------------------------------------------------------------------
Label2ChangePosition(const QPointF & pos)173 void VToolDoublePoint::Label2ChangePosition(const QPointF &pos)
174 {
175     UpdateNamePosition(p2id, pos - secondPoint->pos());
176 }
177 
178 //---------------------------------------------------------------------------------------------------------------------
Disable(bool disable,const QString & namePP)179 void VToolDoublePoint::Disable(bool disable, const QString &namePP)
180 {
181     const bool enabled = !CorrectDisable(disable, namePP);
182     this->setEnabled(enabled);
183     firstPoint->SetEnabled(enabled);
184     secondPoint->SetEnabled(enabled);
185 }
186 
187 //---------------------------------------------------------------------------------------------------------------------
EnableToolMove(bool move)188 void VToolDoublePoint::EnableToolMove(bool move)
189 {
190     firstPoint->EnableToolMove(move);
191     secondPoint->EnableToolMove(move);
192 }
193 
194 //---------------------------------------------------------------------------------------------------------------------
Point1Choosed()195 void VToolDoublePoint::Point1Choosed()
196 {
197     emit ChoosedTool(p1id, SceneObject::Point);
198 }
199 
200 //---------------------------------------------------------------------------------------------------------------------
Point2Choosed()201 void VToolDoublePoint::Point2Choosed()
202 {
203     emit ChoosedTool(p2id, SceneObject::Point);
204 }
205 
206 //---------------------------------------------------------------------------------------------------------------------
Point1Selected(bool selected)207 void VToolDoublePoint::Point1Selected(bool selected)
208 {
209     emit ChangedToolSelection(selected, p1id, m_id);
210 }
211 
212 //---------------------------------------------------------------------------------------------------------------------
Point2Selected(bool selected)213 void VToolDoublePoint::Point2Selected(bool selected)
214 {
215     emit ChangedToolSelection(selected, p2id, m_id);
216 }
217 
218 //---------------------------------------------------------------------------------------------------------------------
FullUpdateFromFile()219 void VToolDoublePoint::FullUpdateFromFile()
220 {
221     ReadAttributes();
222     firstPoint->setToolTip(ComplexToolTip(p1id));
223     firstPoint->RefreshPointGeometry(*VAbstractTool::data.GeometricObject<VPointF>(p1id));
224     secondPoint->setToolTip(ComplexToolTip(p2id));
225     secondPoint->RefreshPointGeometry(*VAbstractTool::data.GeometricObject<VPointF>(p2id));
226     SetVisualization();
227 }
228 
229 //---------------------------------------------------------------------------------------------------------------------
ChangeLabelPosition(quint32 id,const QPointF & pos)230 void VToolDoublePoint::ChangeLabelPosition(quint32 id, const QPointF &pos)
231 {
232     if (id == p1id)
233     {
234         QSharedPointer<VPointF> point = VAbstractTool::data.GeometricObject<VPointF>(p1id);
235         point->setMx(pos.x());
236         point->setMy(pos.y());
237         firstPoint->RefreshPointGeometry(*(point.data()));
238 
239         if (QGraphicsScene *sc = firstPoint->scene())
240         {
241             VMainGraphicsView::NewSceneRect(sc, VAbstractValApplication::VApp()->getSceneView(), firstPoint);
242         }
243     }
244     else if (id == p2id)
245     {
246         QSharedPointer<VPointF> point = VAbstractTool::data.GeometricObject<VPointF>(p2id);
247         point->setMx(pos.x());
248         point->setMy(pos.y());
249         secondPoint->RefreshPointGeometry(*(point.data()));
250 
251         if (QGraphicsScene *sc = secondPoint->scene())
252         {
253             VMainGraphicsView::NewSceneRect(sc, VAbstractValApplication::VApp()->getSceneView(), secondPoint);
254         }
255     }
256 }
257 
258 //---------------------------------------------------------------------------------------------------------------------
AllowHover(bool enabled)259 void VToolDoublePoint::AllowHover(bool enabled)
260 {
261     firstPoint->setAcceptHoverEvents(enabled);
262     secondPoint->setAcceptHoverEvents(enabled);
263 }
264 
265 //---------------------------------------------------------------------------------------------------------------------
AllowSelecting(bool enabled)266 void VToolDoublePoint::AllowSelecting(bool enabled)
267 {
268     firstPoint->setFlag(QGraphicsItem::ItemIsSelectable, enabled);
269     secondPoint->setFlag(QGraphicsItem::ItemIsSelectable, enabled);
270 }
271 
272 //---------------------------------------------------------------------------------------------------------------------
AllowLabelHover(bool enabled)273 void VToolDoublePoint::AllowLabelHover(bool enabled)
274 {
275     firstPoint->AllowLabelHover(enabled);
276     secondPoint->AllowLabelHover(enabled);
277 }
278 
279 //---------------------------------------------------------------------------------------------------------------------
AllowLabelSelecting(bool enabled)280 void VToolDoublePoint::AllowLabelSelecting(bool enabled)
281 {
282     firstPoint->AllowLabelSelecting(enabled);
283     secondPoint->AllowLabelSelecting(enabled);
284 }
285 
286 //---------------------------------------------------------------------------------------------------------------------
ToolSelectionType(const SelectionType & type)287 void VToolDoublePoint::ToolSelectionType(const SelectionType &type)
288 {
289     VAbstractTool::ToolSelectionType(type);
290     firstPoint->ToolSelectionType(type);
291     secondPoint->ToolSelectionType(type);
292 }
293 
294 //---------------------------------------------------------------------------------------------------------------------
UpdateNamePosition(quint32 id,const QPointF & pos)295 void VToolDoublePoint::UpdateNamePosition(quint32 id, const QPointF &pos)
296 {
297     if (id == p1id)
298     {
299         VAbstractApplication::VApp()->getUndoStack()->push(
300                     new MoveDoubleLabel(doc, pos, MoveDoublePoint::FirstPoint, m_id, p1id));
301     }
302     else if (id == p2id)
303     {
304         VAbstractApplication::VApp()->getUndoStack()->push(
305                     new MoveDoubleLabel(doc, pos, MoveDoublePoint::SecondPoint, m_id, p2id));
306     }
307 }
308 
309 //---------------------------------------------------------------------------------------------------------------------
310 /**
311  * @brief itemChange hadle item change.
312  * @param change change.
313  * @param value value.
314  * @return value.
315  */
itemChange(QGraphicsItem::GraphicsItemChange change,const QVariant & value)316 QVariant VToolDoublePoint::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value)
317 {
318     if (change == QGraphicsItem::ItemSelectedHasChanged)
319     {
320         if (value == true)
321         {
322             // do stuff if selected
323             this->setFocus();
324         }
325         else
326         {
327             // do stuff if not selected
328         }
329     }
330 
331     return QGraphicsPathItem::itemChange(change, value);
332 }
333 
334 //---------------------------------------------------------------------------------------------------------------------
335 /**
336  * @brief keyReleaseEvent handle key release events.
337  * @param event key release event.
338  */
keyReleaseEvent(QKeyEvent * event)339 void VToolDoublePoint::keyReleaseEvent(QKeyEvent *event)
340 {
341     switch (event->key())
342     {
343         case Qt::Key_Delete:
344             try
345             {
346                 DeleteToolWithConfirm();
347             }
348             catch(const VExceptionToolWasDeleted &e)
349             {
350                 Q_UNUSED(e)
351                 return;//Leave this method immediately!!!
352             }
353             break;
354         default:
355             break;
356     }
357     QGraphicsPathItem::keyReleaseEvent ( event );
358 }
359 
360 //---------------------------------------------------------------------------------------------------------------------
contextMenuEvent(QGraphicsSceneContextMenuEvent * event)361 void VToolDoublePoint::contextMenuEvent(QGraphicsSceneContextMenuEvent *event)
362 {
363     ShowContextMenu(event);
364 }
365 
366 //---------------------------------------------------------------------------------------------------------------------
SaveOptions(QDomElement & tag,QSharedPointer<VGObject> & obj)367 void VToolDoublePoint::SaveOptions(QDomElement &tag, QSharedPointer<VGObject> &obj)
368 {
369     VDrawTool::SaveOptions(tag, obj);
370 
371     auto SavePoint1 = [this](QDomElement &tag, const QSharedPointer<VPointF> &point)
372     {
373         doc->SetAttribute(tag, AttrName1, point->name());
374         doc->SetAttribute(tag, AttrMx1, VAbstractValApplication::VApp()->fromPixel(point->mx()));
375         doc->SetAttribute(tag, AttrMy1, VAbstractValApplication::VApp()->fromPixel(point->my()));
376         doc->SetAttribute<bool>(tag, AttrShowLabel1, point->IsShowLabel());
377     };
378 
379     auto SavePoint2 = [this](QDomElement &tag, const QSharedPointer<VPointF> &point)
380     {
381         doc->SetAttribute(tag, AttrName2, point->name());
382         doc->SetAttribute(tag, AttrMx2, VAbstractValApplication::VApp()->fromPixel(point->mx()));
383         doc->SetAttribute(tag, AttrMy2, VAbstractValApplication::VApp()->fromPixel(point->my()));
384         doc->SetAttribute<bool>(tag, AttrShowLabel2, point->IsShowLabel());
385     };
386 
387     if (obj->id() == p1id)
388     {
389         QSharedPointer<VPointF> point = qSharedPointerDynamicCast<VPointF>(obj);
390         SCASSERT(point.isNull() == false)
391 
392         SavePoint1(tag, point);
393     }
394     else if (obj->id() == p2id)
395     {
396         QSharedPointer<VPointF> point = qSharedPointerDynamicCast<VPointF>(obj);
397         SCASSERT(point.isNull() == false)
398 
399         SavePoint2(tag, point);
400     }
401     else
402     {
403         doc->SetAttribute(tag, AttrPoint1, p1id);
404         SavePoint1(tag, VAbstractTool::data.GeometricObject<VPointF>(p1id));
405 
406         doc->SetAttribute(tag, AttrPoint2, p2id);
407         SavePoint2(tag, VAbstractTool::data.GeometricObject<VPointF>(p2id));
408     }
409 }
410 
411 //---------------------------------------------------------------------------------------------------------------------
AddToFile()412 void VToolDoublePoint::AddToFile()
413 {
414     QDomElement domElement = doc->createElement(getTagName());
415     QSharedPointer<VGObject> obj = VContainer::GetFakeGObject(m_id);
416     SaveOptions(domElement, obj);
417     AddToCalculation(domElement);
418 }
419 
420 //---------------------------------------------------------------------------------------------------------------------
ChangeLabelVisibility(quint32 id,bool visible)421 void VToolDoublePoint::ChangeLabelVisibility(quint32 id, bool visible)
422 {
423     if (id == p1id)
424     {
425         VAbstractApplication::VApp()->getUndoStack()->push(
426                     new ShowDoubleLabel(doc, m_id, p1id, visible, ShowDoublePoint::FirstPoint));
427     }
428     else if (id == p2id)
429     {
430         VAbstractApplication::VApp()->getUndoStack()->push(
431                     new ShowDoubleLabel(doc, m_id, p2id, visible, ShowDoublePoint::SecondPoint));
432     }
433 }
434 
435 //---------------------------------------------------------------------------------------------------------------------
ComplexToolTip(quint32 itemId) const436 QString VToolDoublePoint::ComplexToolTip(quint32 itemId) const
437 {
438     const QSharedPointer<VPointF> point = VAbstractTool::data.GeometricObject<VPointF>(itemId);
439 
440     const QString toolTip = QString("<table>"
441                                     "<tr> <td><b>%1:</b> %2</td> </tr>"
442                                     "%3"
443                                     "</table>")
444             .arg(tr("Label"), point->name(), MakeToolTip());
445     return toolTip;
446 }
447