/************************************************************************ ** ** @file ** @author Roman Telezhynskyi ** @date 12 9, 2016 ** ** @brief ** @copyright ** This source code is part of the Valentine project, a pattern making ** program, whose allow create and modeling patterns of clothing. ** Copyright (C) 2016 Valentina project ** All Rights Reserved. ** ** Valentina is free software: you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation, either version 3 of the License, or ** (at your option) any later version. ** ** Valentina is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with Valentina. If not, see . ** *************************************************************************/ #include "vabstractoperation.h" #include "../../../undocommands/label/operationmovelabel.h" #include "../vgeometry/vpointf.h" const QString VAbstractOperation::TagItem = QStringLiteral("item"); const QString VAbstractOperation::TagSource = QStringLiteral("source"); const QString VAbstractOperation::TagDestination = QStringLiteral("destination"); //--------------------------------------------------------------------------------------------------------------------- QString VAbstractOperation::getTagName() const { return VAbstractPattern::TagOperation; } //--------------------------------------------------------------------------------------------------------------------- void VAbstractOperation::SetEnabled(bool enabled) { this->setEnabled(enabled); } //--------------------------------------------------------------------------------------------------------------------- QString VAbstractOperation::Suffix() const { return suffix; } //--------------------------------------------------------------------------------------------------------------------- void VAbstractOperation::SetSuffix(const QString &suffix) { // Don't know if need check name here. this->suffix = suffix; QSharedPointer obj = VContainer::GetFakeGObject(id); SaveOption(obj); } //--------------------------------------------------------------------------------------------------------------------- void VAbstractOperation::GroupVisibility(quint32 object, bool visible) { if (operatedObjects.contains(object)) { VAbstractSimple *obj = operatedObjects.value(object); if (obj && obj->GetType() == GOType::Point) { VSimplePoint *item = qobject_cast(obj); SCASSERT(item != nullptr) item->setVisible(visible); } else { VSimpleCurve *item = qobject_cast(obj); SCASSERT(item != nullptr) item->setVisible(visible); } } } //--------------------------------------------------------------------------------------------------------------------- void VAbstractOperation::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) { Q_UNUSED(painter) Q_UNUSED(option) Q_UNUSED(widget) } //--------------------------------------------------------------------------------------------------------------------- void VAbstractOperation::ExtractData(const QDomElement &domElement, QVector &source, QVector &destination) { const QDomNodeList nodeList = domElement.childNodes(); for (qint32 i = 0; i < nodeList.size(); ++i) { const QDomElement dataElement = nodeList.at(i).toElement(); if (not dataElement.isNull() && dataElement.tagName() == TagSource) { source.clear(); const QDomNodeList srcList = dataElement.childNodes(); for (qint32 j = 0; j < srcList.size(); ++j) { const QDomElement element = srcList.at(j).toElement(); if (not element.isNull()) { source.append(VDomDocument::GetParametrUInt(element, AttrIdObject, NULL_ID_STR)); } } } if (not dataElement.isNull() && dataElement.tagName() == TagDestination) { destination.clear(); const QDomNodeList srcList = dataElement.childNodes(); for (qint32 j = 0; j < srcList.size(); ++j) { const QDomElement element = srcList.at(j).toElement(); if (not element.isNull()) { DestinationItem d; d.id = VDomDocument::GetParametrUInt(element, AttrIdObject, NULL_ID_STR); d.mx = qApp->toPixel(VDomDocument::GetParametrDouble(element, AttrMx, QString::number(INT_MAX))); d.my = qApp->toPixel(VDomDocument::GetParametrDouble(element, AttrMy, QString::number(INT_MAX))); destination.append(d); } } } } } //--------------------------------------------------------------------------------------------------------------------- void VAbstractOperation::FullUpdateFromFile() { ReadAttributes(); QMapIterator i(operatedObjects); while (i.hasNext()) { i.next(); if (i.value()->GetType() == GOType::Point) { VSimplePoint *item = qobject_cast(i.value()); SCASSERT(item != nullptr) item->RefreshGeometry(*VAbstractTool::data.GeometricObject(i.key())); } else { VSimpleCurve *item = qobject_cast(i.value()); SCASSERT(item != nullptr) item->RefreshGeometry(VAbstractTool::data.GeometricObject(i.key())); } } SetVisualization(); } //--------------------------------------------------------------------------------------------------------------------- void VAbstractOperation::SetFactor(qreal factor) { VDrawTool::SetFactor(factor); QMapIterator i(operatedObjects); while (i.hasNext()) { i.next(); if (i.value()->GetType() == GOType::Point) { VSimplePoint *item = qobject_cast(i.value()); SCASSERT(item != nullptr) item->RefreshGeometry(*VAbstractTool::data.GeometricObject(i.key())); } else { VSimpleCurve *item = qobject_cast(i.value()); SCASSERT(item != nullptr) item->RefreshGeometry(VAbstractTool::data.GeometricObject(i.key())); } } } //--------------------------------------------------------------------------------------------------------------------- void VAbstractOperation::AllowHover(bool enabled) { QMapIterator i(operatedObjects); while (i.hasNext()) { i.next(); if (i.value()->GetType() == GOType::Point) { VSimplePoint *item = qobject_cast(i.value()); SCASSERT(item != nullptr) item->setAcceptHoverEvents(enabled); } else { VSimpleCurve *item = qobject_cast(i.value()); SCASSERT(item != nullptr) item->setAcceptHoverEvents(enabled); } } } //--------------------------------------------------------------------------------------------------------------------- void VAbstractOperation::AllowSelecting(bool enabled) { QMapIterator i(operatedObjects); while (i.hasNext()) { i.next(); if (i.value()->GetType() == GOType::Point) { VSimplePoint *item = qobject_cast(i.value()); SCASSERT(item != nullptr) item->setFlag(QGraphicsItem::ItemIsSelectable, enabled); } else { VSimpleCurve *item = qobject_cast(i.value()); SCASSERT(item != nullptr) item->setFlag(QGraphicsItem::ItemIsSelectable, enabled); } } } //--------------------------------------------------------------------------------------------------------------------- void VAbstractOperation::AllowPointHover(bool enabled) { QMapIterator i(operatedObjects); while (i.hasNext()) { i.next(); if (i.value()->GetType() == GOType::Point) { VSimplePoint *item = qobject_cast(i.value()); SCASSERT(item != nullptr) item->setAcceptHoverEvents(enabled); } } } //--------------------------------------------------------------------------------------------------------------------- void VAbstractOperation::AllowPointSelecting(bool enabled) { QMapIterator i(operatedObjects); while (i.hasNext()) { i.next(); if (i.value()->GetType() == GOType::Point) { VSimplePoint *item = qobject_cast(i.value()); SCASSERT(item != nullptr) item->setFlag(QGraphicsItem::ItemIsSelectable, enabled); } } } //--------------------------------------------------------------------------------------------------------------------- void VAbstractOperation::AllowPointLabelHover(bool enabled) { QMapIterator i(operatedObjects); while (i.hasNext()) { i.next(); if (i.value()->GetType() == GOType::Point) { VSimplePoint *item = qobject_cast(i.value()); SCASSERT(item != nullptr) item->AllowLabelHover(enabled); } } } //--------------------------------------------------------------------------------------------------------------------- void VAbstractOperation::AllowPointLabelSelecting(bool enabled) { QMapIterator i(operatedObjects); while (i.hasNext()) { i.next(); if (i.value()->GetType() == GOType::Point) { VSimplePoint *item = qobject_cast(i.value()); SCASSERT(item != nullptr) item->AllowLabelSelecting(enabled); } } } //--------------------------------------------------------------------------------------------------------------------- void VAbstractOperation::AllowSplineHover(bool enabled) { AllowCurveHover(enabled, GOType::Spline); } //--------------------------------------------------------------------------------------------------------------------- void VAbstractOperation::AllowSplineSelecting(bool enabled) { AllowCurveSelecting(enabled, GOType::Spline); } //--------------------------------------------------------------------------------------------------------------------- void VAbstractOperation::AllowSplinePathHover(bool enabled) { AllowCurveHover(enabled, GOType::SplinePath); } //--------------------------------------------------------------------------------------------------------------------- void VAbstractOperation::AllowSplinePathSelecting(bool enabled) { AllowCurveSelecting(enabled, GOType::SplinePath); } //--------------------------------------------------------------------------------------------------------------------- void VAbstractOperation::AllowArcHover(bool enabled) { AllowCurveHover(enabled, GOType::Arc); } //--------------------------------------------------------------------------------------------------------------------- void VAbstractOperation::AllowArcSelecting(bool enabled) { AllowCurveSelecting(enabled, GOType::Arc); } //--------------------------------------------------------------------------------------------------------------------- void VAbstractOperation::AllowElArcHover(bool enabled) { AllowCurveHover(enabled, GOType::EllipticalArc); } //--------------------------------------------------------------------------------------------------------------------- void VAbstractOperation::AllowElArcSelecting(bool enabled) { AllowCurveSelecting(enabled, GOType::EllipticalArc); } //--------------------------------------------------------------------------------------------------------------------- void VAbstractOperation::ToolSelectionType(const SelectionType &type) { VAbstractTool::ToolSelectionType(type); QMapIterator i(operatedObjects); while (i.hasNext()) { i.next(); if (i.value()->GetType() == GOType::Point) { VSimplePoint *item = qobject_cast(i.value()); SCASSERT(item != nullptr) item->ToolSelectionType(selectionType); } } } //--------------------------------------------------------------------------------------------------------------------- void VAbstractOperation::Disable(bool disable, const QString &namePP) { enabled = !CorrectDisable(disable, namePP); SetEnabled(enabled); QMapIterator i(operatedObjects); while (i.hasNext()) { i.next(); i.value()->SetEnabled(enabled); } } //--------------------------------------------------------------------------------------------------------------------- void VAbstractOperation::ObjectSelected(bool selected, quint32 objId) { emit ChangedToolSelection(selected, objId, id); } //--------------------------------------------------------------------------------------------------------------------- void VAbstractOperation::DeleteFromLabel() { try { DeleteTool(); } catch(const VExceptionToolWasDeleted &e) { Q_UNUSED(e) return;//Leave this method immediately!!! } } //--------------------------------------------------------------------------------------------------------------------- void VAbstractOperation::LabelChangePosition(const QPointF &pos, quint32 labelId) { if (operatedObjects.contains(labelId)) { VAbstractSimple *obj = operatedObjects.value(labelId); if (obj && obj->GetType() == GOType::Point) { VSimplePoint *item = qobject_cast(obj); SCASSERT(item != nullptr) ChangePosition(item, labelId, pos); } } } //--------------------------------------------------------------------------------------------------------------------- VAbstractOperation::VAbstractOperation(VAbstractPattern *doc, VContainer *data, quint32 id, const QString &suffix, const QVector &source, const QVector &destination, QGraphicsItem *parent) : VDrawTool(doc, data, id), QGraphicsLineItem(parent), suffix(suffix), source(source), destination(destination), operatedObjects() { } //--------------------------------------------------------------------------------------------------------------------- void VAbstractOperation::AddToFile() { QDomElement domElement = doc->createElement(getTagName()); QSharedPointer obj = VContainer::GetFakeGObject(id); SaveOptions(domElement, obj); AddToCalculation(domElement); } //--------------------------------------------------------------------------------------------------------------------- void VAbstractOperation::RefreshDataInFile() { QDomElement domElement = doc->elementById(id); if (domElement.isElement()) { QSharedPointer obj = VContainer::GetFakeGObject(id); SaveOptions(domElement, obj); } else { qCDebug(vTool, "Can't find tool with id = %u", id); } } //--------------------------------------------------------------------------------------------------------------------- void VAbstractOperation::UpdateNamePosition(quint32 id) { const QSharedPointer point = VAbstractTool::data.GeometricObject(id); auto moveLabel = new OperationMoveLabel(this->id, doc, point->mx(), point->my(), id); connect(moveLabel, &OperationMoveLabel::ChangePosition, this, &VAbstractOperation::DoChangePosition); qApp->getUndoStack()->push(moveLabel); } //--------------------------------------------------------------------------------------------------------------------- void VAbstractOperation::SaveSourceDestination(QDomElement &tag) { doc->RemoveAllChildren(tag); QDomElement tagObjects = doc->createElement(TagSource); for (int i = 0; i < source.size(); ++i) { QDomElement item = doc->createElement(TagItem); doc->SetAttribute(item, AttrIdObject, source.at(i)); tagObjects.appendChild(item); } tag.appendChild(tagObjects); tagObjects = doc->createElement(TagDestination); for (int i = 0; i < destination.size(); ++i) { QDomElement item = doc->createElement(TagItem); doc->SetAttribute(item, AttrIdObject, destination.at(i).id); if (not VFuzzyComparePossibleNulls(destination.at(i).mx, INT_MAX) && not VFuzzyComparePossibleNulls(destination.at(i).my, INT_MAX)) { doc->SetAttribute(item, AttrMx, qApp->fromPixel(destination.at(i).mx)); doc->SetAttribute(item, AttrMy, qApp->fromPixel(destination.at(i).my)); } tagObjects.appendChild(item); } tag.appendChild(tagObjects); } //--------------------------------------------------------------------------------------------------------------------- VSimpleCurve *VAbstractOperation::InitCurve(quint32 id, VContainer *data, GOType curveType) { VSimpleCurve *curve = new VSimpleCurve(id, QColor(baseColor), *data->GetPatternUnit(), &factor); curve->setParentItem(this); curve->SetType(curveType); connect(curve, &VSimpleCurve::Selected, this, &VAbstractOperation::ObjectSelected); connect(curve, &VSimpleCurve::ShowContextMenu, RECEIVER(this)[this](QGraphicsSceneContextMenuEvent * event) { contextMenuEvent(event); }); connect(curve, &VSimpleCurve::Delete, this, &VAbstractOperation::DeleteFromLabel); curve->RefreshGeometry(VAbstractTool::data.GeometricObject(id)); operatedObjects.insert(id, curve); return curve; } //--------------------------------------------------------------------------------------------------------------------- void VAbstractOperation::DoChangePosition(quint32 id, qreal mx, qreal my) { if (operatedObjects.contains(id)) { VPointF *point = new VPointF(*VAbstractTool::data.GeometricObject(id)); point->setMx(mx); point->setMy(my); VAbstractTool::data.UpdateGObject(id, point); VSimplePoint *item = qobject_cast(operatedObjects.value(id)); SCASSERT(item != nullptr) item->RefreshGeometry(*point); } } //--------------------------------------------------------------------------------------------------------------------- void VAbstractOperation::AllowCurveHover(bool enabled, GOType type) { QMapIterator i(operatedObjects); while (i.hasNext()) { i.next(); if (i.value()->GetType() != GOType::Point) { VSimpleCurve *item = qobject_cast(i.value()); SCASSERT(item != nullptr) if (item->GetType() == type) { item->setAcceptHoverEvents(enabled); } } } } //--------------------------------------------------------------------------------------------------------------------- void VAbstractOperation::AllowCurveSelecting(bool enabled, GOType type) { QMapIterator i(operatedObjects); while (i.hasNext()) { i.next(); if (i.value()->GetType() != GOType::Point) { VSimpleCurve *item = qobject_cast(i.value()); SCASSERT(item != nullptr) if (item->GetType() == type) { item->setFlag(QGraphicsItem::ItemIsSelectable, enabled); } } } } //--------------------------------------------------------------------------------------------------------------------- void VAbstractOperation::ChangePosition(QGraphicsItem *item, quint32 id, const QPointF &pos) { const QPointF p = pos - item->pos(); DoChangePosition(id, p.x(), p.y()); UpdateNamePosition(id); } //--------------------------------------------------------------------------------------------------------------------- void VAbstractOperation::InitOperatedObjects() { for (int i = 0; i < destination.size(); ++i) { const DestinationItem object = destination.at(i); const QSharedPointer obj = VAbstractTool::data.GetGObject(object.id); // This check helps to find missed objects in the switch Q_STATIC_ASSERT_X(static_cast(GOType::Unknown) == 7, "Not all objects were handled."); QT_WARNING_PUSH QT_WARNING_DISABLE_GCC("-Wswitch-default") switch(static_cast(obj->getType())) { case GOType::Point: { VSimplePoint *point = new VSimplePoint(object.id, QColor(baseColor), *VAbstractTool::data.GetPatternUnit(), &factor); point->setParentItem(this); point->SetType(GOType::Point); connect(point, &VSimplePoint::Choosed, RECEIVER(this)[this](quint32 id) { emit ChoosedTool(id, SceneObject::Point); }); connect(point, &VSimplePoint::Selected, this, &VAbstractOperation::ObjectSelected); connect(point, &VSimplePoint::ShowContextMenu, RECEIVER(this)[this](QGraphicsSceneContextMenuEvent * event) { contextMenuEvent(event); }); connect(point, &VSimplePoint::Delete, this, &VAbstractOperation::DeleteFromLabel); connect(point, &VSimplePoint::NameChangedPosition, this, &VAbstractOperation::LabelChangePosition); point->RefreshGeometry(*VAbstractTool::data.GeometricObject(object.id)); operatedObjects.insert(object.id, point); break; } case GOType::Arc: { VSimpleCurve *curve = InitCurve(object.id, &(VAbstractTool::data), obj->getType()); connect(curve, &VSimpleCurve::Choosed, RECEIVER(this)[this](quint32 id) { emit ChoosedTool(id, SceneObject::Arc); }); break; } case GOType::EllipticalArc: { VSimpleCurve *curve = InitCurve(object.id, &(VAbstractTool::data), obj->getType()); connect(curve, &VSimpleCurve::Choosed, RECEIVER(this)[this](quint32 id) { emit ChoosedTool(id, SceneObject::ElArc); }); break; } case GOType::Spline: case GOType::CubicBezier: { VSimpleCurve *curve = InitCurve(object.id, &(VAbstractTool::data), obj->getType()); connect(curve, &VSimpleCurve::Choosed, RECEIVER(this)[this](quint32 id) { emit ChoosedTool(id, SceneObject::Spline); }); break; } case GOType::SplinePath: case GOType::CubicBezierPath: { VSimpleCurve *curve = InitCurve(object.id, &(VAbstractTool::data), obj->getType()); connect(curve, &VSimpleCurve::Choosed, RECEIVER(this)[this](quint32 id) { emit ChoosedTool(id, SceneObject::SplinePath); }); break; } case GOType::Unknown: break; } QT_WARNING_POP } }