Seamly2D
Code documentation
vtoolbasepoint.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  ** @file vtoolsinglepoint.cpp
3  ** @author Douglas S Caskey
4  ** @date Dec 27, 2022
5  **
6  ** @copyright
7  ** Copyright (C) 2017 - 2022 Seamly, LLC
8  ** https://github.com/fashionfreedom/seamly2d
9  **
10  ** @brief
11  ** Seamly2D is free software: you can redistribute it and/or modify
12  ** it under the terms of the GNU General Public License as published by
13  ** the Free Software Foundation, either version 3 of the License, or
14  ** (at your option) any later version.
15  **
16  ** Seamly2D is distributed in the hope that it will be useful,
17  ** but WITHOUT ANY WARRANTY; without even the implied warranty of
18  ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  ** GNU General Public License for more details.
20  **
21  ** You should have received a copy of the GNU General Public License
22  ** along with Seamly2D. If not, see <http://www.gnu.org/licenses/>.
23  **************************************************************************/
24 
25 /************************************************************************
26  **
27  ** @file vtoolsinglepoint.cpp
28  ** @author Roman Telezhynskyi <dismine(at)gmail.com>
29  ** @date November 15, 2013
30  **
31  ** @brief
32  ** @copyright
33  ** This source code is part of the Valentina project, a pattern making
34  ** program, whose allow create and modeling patterns of clothing.
35  ** Copyright (C) 2013-2015 Valentina project
36  ** <https://bitbucket.org/dismine/valentina> All Rights Reserved.
37  **
38  ** Valentina is free software: you can redistribute it and/or modify
39  ** it under the terms of the GNU General Public License as published by
40  ** the Free Software Foundation, either version 3 of the License, or
41  ** (at your option) any later version.
42  **
43  ** Valentina is distributed in the hope that it will be useful,
44  ** but WITHOUT ANY WARRANTY; without even the implied warranty of
45  ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
46  ** GNU General Public License for more details.
47  **
48  ** You should have received a copy of the GNU General Public License
49  ** along with Valentina. If not, see <http://www.gnu.org/licenses/>.
50  **
51  *************************************************************************/
52 
53 #include "vtoolbasepoint.h"
54 
55 #include <QApplication>
56 #include <QEvent>
57 #include <QFlags>
58 #include <QGraphicsLineItem>
59 #include <QGraphicsScene>
60 #include <QGraphicsSceneMouseEvent>
61 #include <QGraphicsView>
62 #include <QList>
63 #include <QMessageBox>
64 #include <QPen>
65 #include <QPointF>
66 #include <QPolygonF>
67 #include <QRectF>
68 #include <QSharedPointer>
69 #include <QStaticStringData>
70 #include <QStringData>
71 #include <QStringDataPtr>
72 #include <QUndoStack>
73 #include <new>
74 
75 #include "vtoolsinglepoint.h"
76 #include "../ifc/exception/vexception.h"
77 #include "../ifc/ifcdef.h"
78 #include "../vgeometry/vgobject.h"
79 #include "../vgeometry/vpointf.h"
80 #include "../vmisc/logging.h"
81 #include "../vmisc/vabstractapplication.h"
82 #include "../vpatterndb/vcontainer.h"
83 #include "../vwidgets/vgraphicssimpletextitem.h"
84 #include "../vwidgets/vmaingraphicsscene.h"
85 #include "../vwidgets/vmaingraphicsview.h"
86 #include "../../vdrawtool.h"
87 #include "../../../vabstracttool.h"
88 #include "../../../vdatatool.h"
89 #include "../../../../dialogs/tools/dialogtool.h"
90 #include "../../../../dialogs/tools/dialogsinglepoint.h"
91 #include "../../../../undocommands/add_draftblock.h"
92 #include "../../../../undocommands/delete_draftblock.h"
93 #include "../../../../undocommands/movespoint.h"
94 
95 const QString VToolBasePoint::ToolType = QStringLiteral("single");
96 
97 //---------------------------------------------------------------------------------------------------------------------
98 /**
99  * @brief VToolBasePoint constructor.
100  * @param doc dom document container.
101  * @param data container with variables.
102  * @param id object id in container.
103  * @param typeCreation way we create this tool.
104  * @param parent parent object.
105  */
106 VToolBasePoint::VToolBasePoint (VAbstractPattern *doc, VContainer *data, quint32 id, const Source &typeCreation,
107  const QString &draftBlockName, QGraphicsItem * parent )
108  : VToolSinglePoint(doc, data, id, QColor(Qt::red), parent)
109  , draftBlockName(draftBlockName)
110 {
111  this->setFlag(QGraphicsItem::ItemIsMovable, true);
112  this->setFlag(QGraphicsItem::ItemSendsGeometryChanges, true);
113  //m_pointName->setBrush(Qt::black);
114  ToolCreation(typeCreation);
115 }
116 
117 //---------------------------------------------------------------------------------------------------------------------
118 /**
119  * @brief setDialog set dialog when user want change tool option.
120  */
122 {
123  SCASSERT(not m_dialog.isNull())
125  SCASSERT(not dialogTool.isNull())
127  dialogTool->SetData(p->name(), static_cast<QPointF>(*p));
128 }
129 
130 //---------------------------------------------------------------------------------------------------------------------
131 VToolBasePoint *VToolBasePoint::Create(quint32 _id, const QString &activeDraftBlock, VPointF *point,
132  VMainGraphicsScene *scene, VAbstractPattern *doc, VContainer *data,
133  const Document &parse, const Source &typeCreation)
134 {
135  SCASSERT(point != nullptr)
136 
137  quint32 id = _id;
138  if (typeCreation == Source::FromGui)
139  {
140  id = data->AddGObject(point);
141  }
142  else
143  {
144  data->UpdateGObject(id, point);
145  if (parse != Document::FullParse)
146  {
147  doc->UpdateToolData(id, data);
148  }
149  }
150 
151  if (parse == Document::FullParse)
152  {
154  VToolBasePoint *spoint = new VToolBasePoint(doc, data, id, typeCreation, activeDraftBlock);
155  scene->addItem(spoint);
156  InitToolConnections(scene, spoint);
157  VAbstractPattern::AddTool(id, spoint);
158  return spoint;
159  }
160  return nullptr;
161 }
162 
163 //---------------------------------------------------------------------------------------------------------------------
165 {
166  Q_UNUSED(show) //don't have any visualization for base point yet
167 }
168 
169 //---------------------------------------------------------------------------------------------------------------------
170 /**
171  * @brief AddToFile add tag with Information about tool into file.
172  */
174 {
175  Q_ASSERT_X(not draftBlockName.isEmpty(), Q_FUNC_INFO, "name pattern piece is empty");
176 
177  QDomElement sPoint = doc->createElement(getTagName());
178 
179  // Create SPoint tag
181  SaveOptions(sPoint, obj);
182 
183  //Create pattern piece structure
184  QDomElement patternPiece = doc->createElement(VAbstractPattern::TagDraftBlock);
185  doc->SetAttribute(patternPiece, AttrName, draftBlockName);
186 
187  QDomElement calcElement = doc->createElement(VAbstractPattern::TagCalculation);
188  calcElement.appendChild(sPoint);
189 
190  patternPiece.appendChild(calcElement);
191  patternPiece.appendChild(doc->createElement(VAbstractPattern::TagModeling));
192  patternPiece.appendChild(doc->createElement(VAbstractPattern::TagPieces));
193 
194  AddDraftBlock *addPP = new AddDraftBlock(patternPiece, doc, draftBlockName);
197  qApp->getUndoStack()->push(addPP);
198 }
199 
200 //---------------------------------------------------------------------------------------------------------------------
201 /**
202  * @brief itemChange handle tool change.
203  * @param change change.
204  * @param value value.
205  * @return value.
206  */
207 QVariant VToolBasePoint::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value)
208 {
209  if (change == ItemPositionChange && scene())
210  {
211  // Each time we move something we call recalculation scene rect. In some cases this can cause moving
212  // objects positions. And this cause infinite redrawing. That's why we wait the finish of saving the last move.
213  static bool changeFinished = true;
214  if (changeFinished)
215  {
216  changeFinished = false;
217  // value - this is new position.
218  QPointF newPos = value.toPointF();
219 
220  MoveSPoint *moveSP = new MoveSPoint(doc, newPos.x(), newPos.y(), m_id, this->scene());
222  qApp->getUndoStack()->push(moveSP);
223  const QList<QGraphicsView *> viewList = scene()->views();
224  if (not viewList.isEmpty())
225  {
226  if (QGraphicsView *view = viewList.at(0))
227  {
228  const int xmargin = 50;
229  const int ymargin = 50;
230 
231  const QRectF viewRect = VMainGraphicsView::SceneVisibleArea(view);
232  const QRectF itemRect = mapToScene(boundingRect()).boundingRect();
233 
234  // If item's rect is bigger than view's rect ensureVisible works very unstable.
235  if (itemRect.height() + 2*ymargin < viewRect.height() &&
236  itemRect.width() + 2*xmargin < viewRect.width())
237  {
238  view->ensureVisible(itemRect, xmargin, ymargin);
239  }
240  else
241  {
242  // Ensure visible only small rect around a cursor
243  VMainGraphicsScene *currentScene = qobject_cast<VMainGraphicsScene *>(scene());
244  SCASSERT(currentScene)
245  const QPointF cursorPosition = currentScene->getScenePos();
246  view->ensureVisible(QRectF(cursorPosition.x()-5, cursorPosition.y()-5, 10, 10));
247  }
248  }
249  }
250  changeFinished = true;
251  }
252  }
253  return VToolSinglePoint::itemChange(change, value);
254 }
255 
256 //---------------------------------------------------------------------------------------------------------------------
257 /**
258  * @brief decrementReferens decrement referens parents objects.
259  */
261 {
262  if (_referens > 1)
263  {
264  --_referens;
265  }
266 }
267 
268 //---------------------------------------------------------------------------------------------------------------------
270 {
272  QPointF pos(qApp->fromPixel(p->x()), qApp->fromPixel(p->y()));
273  return pos;
274 }
275 
276 //---------------------------------------------------------------------------------------------------------------------
277 void VToolBasePoint::SetBasePointPos(const QPointF &pos)
278 {
280  p->setX(qApp->toPixel(pos.x()));
281  p->setY(qApp->toPixel(pos.y()));
282 
283  QSharedPointer<VGObject> obj = qSharedPointerCast<VGObject>(p);
284 
285  SaveOption(obj);
286 }
287 
288 //---------------------------------------------------------------------------------------------------------------------
290 {
291  qCDebug(vTool, "Deleting base point.");
292  qApp->getSceneView()->itemClicked(nullptr);
293  if (ask)
294  {
295  qCDebug(vTool, "Asking.");
296  if (ConfirmDeletion() == QMessageBox::No)
297  {
298  qCDebug(vTool, "User said no.");
299  return;
300  }
301  }
302 
303  qCDebug(vTool, "Begin deleting.");
306  qApp->getUndoStack()->push(deletePP);
307 
308  // Throw exception, this will help prevent case when we forget to immediately quit function.
309  VExceptionToolWasDeleted e("Tool was used after deleting.");
310  throw e;
311 }
312 
313 //---------------------------------------------------------------------------------------------------------------------
314 /**
315  * @brief SaveDialog save options into file after change in dialog.
316  */
317 void VToolBasePoint::SaveDialog(QDomElement &domElement)
318 {
319  SCASSERT(not m_dialog.isNull())
321  SCASSERT(not dialogTool.isNull())
322  const QPointF p = dialogTool->GetPoint();
323  const QString name = dialogTool->getPointName();
324  doc->SetAttribute(domElement, AttrName, name);
325  doc->SetAttribute(domElement, AttrX, QString().setNum(qApp->fromPixel(p.x())));
326  doc->SetAttribute(domElement, AttrY, QString().setNum(qApp->fromPixel(p.y())));
327 }
328 
329 //---------------------------------------------------------------------------------------------------------------------
330 void VToolBasePoint::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
331 {
333 
334  if (flags() & QGraphicsItem::ItemIsMovable)
335  {
337  }
338 }
339 
340 //---------------------------------------------------------------------------------------------------------------------
341 void VToolBasePoint::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
342 {
344 
345  if (flags() & QGraphicsItem::ItemIsMovable)
346  {
347  setCursor(QCursor());
348  }
349 }
350 
351 //---------------------------------------------------------------------------------------------------------------------
352 void VToolBasePoint::mousePressEvent(QGraphicsSceneMouseEvent *event)
353 {
354  if (flags() & QGraphicsItem::ItemIsMovable)
355  {
356  if (event->button() == Qt::LeftButton && event->type() != QEvent::GraphicsSceneMouseDoubleClick)
357  {
359  }
360  }
362 }
363 
364 //---------------------------------------------------------------------------------------------------------------------
365 void VToolBasePoint::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
366 {
367  if (flags() & QGraphicsItem::ItemIsMovable)
368  {
369  if (event->button() == Qt::LeftButton && event->type() != QEvent::GraphicsSceneMouseDoubleClick)
370  {
372  }
373  }
375 }
376 
377 //---------------------------------------------------------------------------------------------------------------------
379 {
381 
382  QSharedPointer<VPointF> point = qSharedPointerDynamicCast<VPointF>(obj);
383  SCASSERT(point.isNull() == false)
384 
386  doc->SetAttribute(tag, AttrX, qApp->fromPixel(point->x()));
387  doc->SetAttribute(tag, AttrY, qApp->fromPixel(point->y()));
388 }
389 
390 //---------------------------------------------------------------------------------------------------------------------
391 void VToolBasePoint::ReadToolAttributes(const QDomElement &domElement)
392 {
393  Q_UNUSED(domElement)
394  // This tool doesn't need read attributes from file.
395 }
396 
397 //---------------------------------------------------------------------------------------------------------------------
399 {
401 
402  const QString toolTipStr = QString("<table>"
403  "<tr> <td><b>%1:</b> %2</td> </tr>"
404  "</table>")
405  .arg(tr("Name"))
406  .arg(point->name());
407  return toolTipStr;
408 }
409 
410 //---------------------------------------------------------------------------------------------------------------------
411 /**
412  * @brief showContextMenu handle context menu events.
413  * @param event context menu event.
414  */
415 void VToolBasePoint::showContextMenu(QGraphicsSceneContextMenuEvent *event, quint32 id)
416 {
417  qCDebug(vTool, "Context menu base point");
418 #ifndef QT_NO_CURSOR
419  QGuiApplication::restoreOverrideCursor();
420  qCDebug(vTool, "Restored overridden cursor");
421 #endif
422 
423  try
424  {
425  if (doc->draftBlockCount() > 1)
426  {
427  qCDebug(vTool, "Draft Block count > 1");
428  ContextMenu<DialogSinglePoint>(event, id, RemoveOption::Enable, Referens::Ignore);
429  }
430  else
431  {
432  qCDebug(vTool, "Draft Block count = 1");
433  ContextMenu<DialogSinglePoint>(event, id, RemoveOption::Disable);
434  }
435  }
436  catch(const VExceptionToolWasDeleted &e)
437  {
438  qCDebug(vTool, "Tool was deleted. Leave method immediately.");
439  Q_UNUSED(e)
440  return;//Leave this method immediately!!!
441  }
442  qCDebug(vTool, "Context menu was closed. Tool was not deleted.");
443 }
444 
445 //---------------------------------------------------------------------------------------------------------------------
446 /**
447  * @brief FullUpdateFromFile update tool data form file.
448  */
450 {
451  refreshPointGeometry(*VAbstractTool::data.GeometricObject<VPointF>(m_id));
452 }
453 
454 //---------------------------------------------------------------------------------------------------------------------
456 {
457  this->setFlag(QGraphicsItem::ItemIsMovable, move);
459 }
The DialogSinglePoint class dialog for ToolSinglePoint. Help create point and edit option.
virtual void LiteParseTree(const Document &parse)=0
static const QString TagPieces
virtual void UpdateToolData(const quint32 &id, VContainer *data)=0
int draftBlockCount() const
static const QString TagModeling
static void AddTool(quint32 id, VDataTool *tool)
AddTool add tool to list tools.
static const QString TagDraftBlock
static const QString TagCalculation
virtual QString getTagName() const Q_DECL_OVERRIDE
static void InitToolConnections(VMainGraphicsScene *scene, T *tool)
VAbstractPattern * doc
doc dom document container
virtual void ToolCreation(const Source &typeCreation)
static int ConfirmDeletion()
static void AddRecord(const quint32 id, const Tool &toolType, VAbstractPattern *doc)
AddRecord add record about tool in history.
const quint32 m_id
id object id.
The VContainer class container of all variables.
Definition: vcontainer.h:141
const QSharedPointer< VGObject > GetGObject(quint32 id) const
GetGObject returns a point by id.
Definition: vcontainer.cpp:150
const QSharedPointer< T > GeometricObject(const quint32 &id) const
Definition: vcontainer.h:266
quint32 AddGObject(VGObject *obj)
AddGObject add new GObject to container.
Definition: vcontainer.cpp:216
void UpdateGObject(quint32 id, T *obj)
UpdateGObject update GObject by id.
Definition: vcontainer.h:374
quint32 _referens
_referens keep count tools what use this tool. If value more than 1 you can't delete tool.
Definition: vdatatool.h:87
VContainer data
data container with data
Definition: vdatatool.h:84
void SetAttribute(QDomElement &domElement, const QString &name, const T &value) const
SetAttribute set attribute in pattern file. Replace "," by ".".
Definition: vdomdocument.h:185
QString activeBlockName
Definition: vdrawtool.h:102
void SaveOption(QSharedPointer< VGObject > &obj)
Definition: vdrawtool.cpp:142
QSharedPointer< DialogTool > m_dialog
m_dialog tool's dialog options.
The VMainGraphicsScene class main scene.
QPointF getScenePos() const
static QRectF SceneVisibleArea(QGraphicsView *view)
The VPointF class keep data of point.
Definition: vpointf.h:75
virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent *event) Q_DECL_OVERRIDE
virtual void refreshPointGeometry(const VPointF &point)
The VToolBasePoint class tool for creation pattern base point. Only base point can move....
QString draftBlockName
virtual void deleteTool(bool ask=true) Q_DECL_OVERRIDE
deleteTool full delete object form scene and file.
static const QString ToolType
virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value) Q_DECL_OVERRIDE
itemChange handle tool change.
virtual void ShowVisualization(bool show) Q_DECL_OVERRIDE
virtual void SaveOptions(QDomElement &tag, QSharedPointer< VGObject > &obj) Q_DECL_OVERRIDE
VToolBasePoint(VAbstractPattern *doc, VContainer *data, quint32 id, const Source &typeCreation, const QString &draftBlockName, QGraphicsItem *parent=nullptr)
VToolBasePoint constructor.
virtual void hoverEnterEvent(QGraphicsSceneHoverEvent *event) Q_DECL_OVERRIDE
virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) Q_DECL_OVERRIDE
mouseReleaseEvent handle mouse release events.
static VToolBasePoint * Create(quint32 _id, const QString &activeDraftBlock, VPointF *point, VMainGraphicsScene *scene, VAbstractPattern *doc, VContainer *data, const Document &parse, const Source &typeCreation)
virtual QString makeToolTip() const Q_DECL_OVERRIDE
virtual void ReadToolAttributes(const QDomElement &domElement) Q_DECL_OVERRIDE
virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent *event) Q_DECL_OVERRIDE
virtual void setDialog() Q_DECL_OVERRIDE
setDialog set dialog when user want change tool option.
virtual void SaveDialog(QDomElement &domElement) Q_DECL_OVERRIDE
SaveDialog save options into file after change in dialog.
virtual void EnableToolMove(bool move) Q_DECL_OVERRIDE
virtual void AddToFile() Q_DECL_OVERRIDE
AddToFile add tag with Information about tool into file.
virtual void mousePressEvent(QGraphicsSceneMouseEvent *event) Q_DECL_OVERRIDE
virtual void showContextMenu(QGraphicsSceneContextMenuEvent *event, quint32 id=NULL_ID) Q_DECL_OVERRIDE
showContextMenu handle context menu events.
QPointF GetBasePointPos() const
void SetBasePointPos(const QPointF &pos)
virtual void decrementReferens() Q_DECL_OVERRIDE
decrementReferens decrement referens parents objects.
virtual void FullUpdateFromFile() Q_DECL_OVERRIDE
FullUpdateFromFile update tool data form file.
The VToolSinglePoint class parent for all tools what create points.
virtual void EnableToolMove(bool move) Q_DECL_OVERRIDE
virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) Q_DECL_OVERRIDE
mouseReleaseEvent handle mouse release events.
QString name() const
virtual void SaveOptions(QDomElement &tag, QSharedPointer< VGObject > &obj) Q_DECL_OVERRIDE
virtual void hoverEnterEvent(QGraphicsSceneHoverEvent *event) Q_DECL_OVERRIDE
virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value) Q_DECL_OVERRIDE
itemChange hadle item change.
virtual void mousePressEvent(QGraphicsSceneMouseEvent *event) Q_DECL_OVERRIDE
void NeedFullParsing()
void ClearScene()
void NeedLiteParsing(const Document &parse)
const QString cursorArrowOpenHand
Definition: def.cpp:191
void SetItemOverrideCursor(QGraphicsItem *item, const QString &pixmapPath, int hotX, int hotY)
Definition: def.cpp:206
const QString cursorArrowCloseHand
Definition: def.cpp:192
#define SCASSERT(cond)
Definition: def.h:317
@ BasePoint
Source
Definition: def.h:106
const QString AttrName
Definition: ifcdef.cpp:76
const QString AttrY
Definition: ifcdef.cpp:89
const QString AttrX
Definition: ifcdef.cpp:88
const QString AttrType
Definition: ifcdef.cpp:73
Document
#define qApp
Definition: vapplication.h:67