diff --git a/ChangeLog.txt b/ChangeLog.txt index a5cd6ebc5..4c8cb824a 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -66,6 +66,7 @@ - Updated Windows installer. - Automatic crash reports. - Improve compatibility with Richpeace CAD. +- New warning "Piece gape position". # Valentina 0.7.52 September 12, 2022 - Fix crash when default locale is ru. diff --git a/src/app/puzzle/dialogs/configpages/puzzlepreferenceslayoutpage.cpp b/src/app/puzzle/dialogs/configpages/puzzlepreferenceslayoutpage.cpp index 48d6a5098..f946cc70a 100644 --- a/src/app/puzzle/dialogs/configpages/puzzlepreferenceslayoutpage.cpp +++ b/src/app/puzzle/dialogs/configpages/puzzlepreferenceslayoutpage.cpp @@ -128,6 +128,8 @@ PuzzlePreferencesLayoutPage::PuzzlePreferencesLayoutPage(QWidget *parent) connect(ui->checkBoxWarningPiecesOutOfBound, &QCheckBox::stateChanged, this, [this]() { m_settingsChanged = true; }); connect(ui->checkBoxFollowGrainline, &QCheckBox::stateChanged, this, [this]() { m_settingsChanged = true; }); + connect(ui->checkBoxWarningPieceGapePosition, &QCheckBox::stateChanged, this, + [this]() { m_settingsChanged = true; }); } //--------------------------------------------------------------------------------------------------------------------- @@ -166,6 +168,7 @@ auto PuzzlePreferencesLayoutPage::Apply() -> QStringList settings->SetLayoutStickyEdges(ui->checkBoxStickyEdges->isChecked()); settings->SetLayoutWarningPiecesOutOfBound(ui->checkBoxWarningPiecesOutOfBound->isChecked()); settings->SetLayoutFollowGrainline(ui->checkBoxFollowGrainline->isChecked()); + settings->SetLayoutWarningPieceGapePosition(ui->checkBoxWarningPieceGapePosition->isChecked()); settings->SetLayoutLineWidth(ui->spinBoxLineWidth->value()); @@ -661,6 +664,7 @@ void PuzzlePreferencesLayoutPage::ReadSettings() ui->checkBoxStickyEdges->setChecked(settings->GetLayoutStickyEdges()); ui->checkBoxWarningPiecesOutOfBound->setChecked(settings->GetLayoutWarningPiecesOutOfBound()); ui->checkBoxFollowGrainline->setChecked(settings->GetLayoutFollowGrainline()); + ui->checkBoxWarningPieceGapePosition->setChecked(settings->GetLayoutWarningPieceGapePosition()); ui->doubleSpinBoxPiecesGap->setMaximum(UnitConvertor(VPSettings::GetMaxLayoutPieceGap(), Unit::Px, LayoutUnit())); SetPieceGap(settings->GetLayoutPieceGap()); diff --git a/src/app/puzzle/dialogs/configpages/puzzlepreferenceslayoutpage.ui b/src/app/puzzle/dialogs/configpages/puzzlepreferenceslayoutpage.ui index 07b800a46..52a9f41f2 100644 --- a/src/app/puzzle/dialogs/configpages/puzzlepreferenceslayoutpage.ui +++ b/src/app/puzzle/dialogs/configpages/puzzlepreferenceslayoutpage.ui @@ -87,7 +87,7 @@ - + @@ -107,7 +107,7 @@ - + @@ -309,6 +309,13 @@ + + + + Warning piece gape position + + + @@ -475,7 +482,7 @@ - + @@ -495,7 +502,7 @@ - + diff --git a/src/app/puzzle/layout/vplayout.cpp b/src/app/puzzle/layout/vplayout.cpp index 9c7b30197..0dfd2f8df 100644 --- a/src/app/puzzle/layout/vplayout.cpp +++ b/src/app/puzzle/layout/vplayout.cpp @@ -90,6 +90,7 @@ auto VPLayout::CreateLayout(QUndoStack *undoStack) -> VPLayoutPtr layout->LayoutSettings().SetWarningSuperpositionOfPieces(settings->GetLayoutWarningPiecesSuperposition()); layout->LayoutSettings().SetWarningPiecesOutOfBound(settings->GetLayoutWarningPiecesOutOfBound()); + layout->LayoutSettings().SetWarningPieceGapePosition(settings->GetLayoutWarningPieceGapePosition()); layout->LayoutSettings().SetFollowGrainline(settings->GetLayoutFollowGrainline()); layout->LayoutSettings().SetStickyEdges(settings->GetLayoutStickyEdges()); layout->LayoutSettings().SetPiecesGap(settings->GetLayoutPieceGap()); diff --git a/src/app/puzzle/layout/vplayoutsettings.cpp b/src/app/puzzle/layout/vplayoutsettings.cpp index 6ece7cdae..99e8cb2c5 100644 --- a/src/app/puzzle/layout/vplayoutsettings.cpp +++ b/src/app/puzzle/layout/vplayoutsettings.cpp @@ -66,6 +66,18 @@ auto VPLayoutSettings::GetWarningPiecesOutOfBound() const -> bool return m_warningPiecesOutOfBound; } +//--------------------------------------------------------------------------------------------------------------------- +void VPLayoutSettings::SetWarningPieceGapePosition(bool state) +{ + m_warningPieceGapePosition = state; +} + +//--------------------------------------------------------------------------------------------------------------------- +auto VPLayoutSettings::GetWarningPieceGapePosition() const -> bool +{ + return m_warningPieceGapePosition; +} + //--------------------------------------------------------------------------------------------------------------------- void VPLayoutSettings::SetTitle(const QString &title) { diff --git a/src/app/puzzle/layout/vplayoutsettings.h b/src/app/puzzle/layout/vplayoutsettings.h index cde24462d..9e1a0b9a9 100644 --- a/src/app/puzzle/layout/vplayoutsettings.h +++ b/src/app/puzzle/layout/vplayoutsettings.h @@ -91,6 +91,9 @@ public: void SetWarningPiecesOutOfBound(bool state); auto GetWarningPiecesOutOfBound() const -> bool; + void SetWarningPieceGapePosition(bool state); + auto GetWarningPieceGapePosition() const -> bool; + /** * @brief SetFollowGrainline Sets the type of grainline for the pieces to follow * @param state the type of grainline @@ -330,6 +333,7 @@ private: bool m_warningSuperpositionOfPieces{false}; bool m_warningPiecesOutOfBound{false}; + bool m_warningPieceGapePosition{false}; QString m_title{}; QString m_description{}; diff --git a/src/app/puzzle/layout/vppiece.cpp b/src/app/puzzle/layout/vppiece.cpp index 807cc37c2..955af0cb2 100644 --- a/src/app/puzzle/layout/vppiece.cpp +++ b/src/app/puzzle/layout/vppiece.cpp @@ -61,7 +61,7 @@ namespace { constexpr qreal minStickyDistance = MmToPixel(3.); constexpr qreal maxStickyDistance = MmToPixel(15.); -constexpr qreal stickyShift = MmToPixel(20.); +constexpr qreal stickyShift = MmToPixel(1.); //--------------------------------------------------------------------------------------------------------------------- auto CutEdge(const QLineF &edge) -> QVector @@ -95,58 +95,6 @@ auto CutEdge(const QLineF &edge) -> QVector } return points; } - -//--------------------------------------------------------------------------------------------------------------------- -auto PrepareStickyPath(const QVector &path) -> QVector -{ - if (path.size() < 2) - { - return path; - } - - QVector stickyPath; - - for (int i = 0; i < path.size(); ++i) - { - stickyPath += CutEdge(QLineF(path.at(i), path.at(i < path.size() - 1 ? i + 1 : 0))); - } - - return stickyPath; -} - -//--------------------------------------------------------------------------------------------------------------------- -auto ClosestDistance(const QVector &path1, const QVector &path2) -> QLineF -{ - return QtConcurrent::blockingMappedReduced( - path1, - [path2](const QPointF &p1) - { - qreal minLocalDistance = std::numeric_limits::max(); - QLineF localClosestDistance; - - for (const auto &p2 : path2) - { - QLineF const d(p1, p2); - qreal const length = d.length(); - if (length < minLocalDistance) - { - minLocalDistance = length; - localClosestDistance = d; - } - } - - return localClosestDistance; - }, - [](QLineF &result, const QLineF &next) - { - qreal const dist1 = result.length(); - qreal const dist2 = next.length(); - if (result.isNull() || dist2 < dist1) - { - result = next; - } - }); -} } // namespace //--------------------------------------------------------------------------------------------------------------------- @@ -352,6 +300,18 @@ void VPPiece::FlipHorizontally() SetHorizontallyFlipped(!IsHorizontallyFlipped()); } +//--------------------------------------------------------------------------------------------------------------------- +auto VPPiece::HasInvalidPieceGapPosition() const -> bool +{ + return m_invalidPieceGapPosition; +} + +//--------------------------------------------------------------------------------------------------------------------- +void VPPiece::SetHasInvalidPieceGapPosition(bool status) +{ + m_invalidPieceGapPosition = status; +} + //--------------------------------------------------------------------------------------------------------------------- auto VPPiece::StickyPosition(qreal &dx, qreal &dy) const -> bool { @@ -436,6 +396,58 @@ auto VPPiece::PathsSuperposition(const QVector &path1, const QVector &path) -> QVector +{ + if (path.size() < 2) + { + return path; + } + + QVector stickyPath; + + for (int i = 0; i < path.size(); ++i) + { + stickyPath += CutEdge(QLineF(path.at(i), path.at(i < path.size() - 1 ? i + 1 : 0))); + } + + return stickyPath; +} + +//--------------------------------------------------------------------------------------------------------------------- +auto VPPiece::ClosestDistance(const QVector &path1, const QVector &path2) -> QLineF +{ + return QtConcurrent::blockingMappedReduced( + path1, + [path2](const QPointF &p1) + { + qreal minLocalDistance = std::numeric_limits::max(); + QLineF localClosestDistance; + + for (const auto &p2 : path2) + { + QLineF const d(p1, p2); + qreal const length = d.length(); + if (length < minLocalDistance) + { + minLocalDistance = length; + localClosestDistance = d; + } + } + + return localClosestDistance; + }, + [](QLineF &result, const QLineF &next) + { + qreal const dist1 = result.length(); + qreal const dist2 = next.length(); + if (result.isNull() || dist2 < dist1) + { + result = next; + } + }); +} + //--------------------------------------------------------------------------------------------------------------------- auto VPPiece::IsValid(QString &error) const -> bool { diff --git a/src/app/puzzle/layout/vppiece.h b/src/app/puzzle/layout/vppiece.h index 9700408d0..f1f742db5 100644 --- a/src/app/puzzle/layout/vppiece.h +++ b/src/app/puzzle/layout/vppiece.h @@ -110,9 +110,14 @@ public: auto HasSuperpositionWithPieces() const -> bool; void SetHasSuperpositionWithPieces(bool newHasSuperpositionWithPieces); + auto HasInvalidPieceGapPosition() const -> bool; + void SetHasInvalidPieceGapPosition(bool status); + auto StickyPosition(qreal &dx, qreal &dy) const -> bool; static auto PathsSuperposition(const QVector &path1, const QVector &path2) -> bool; + static auto PrepareStickyPath(const QVector &path) -> QVector; + static auto ClosestDistance(const QVector &path1, const QVector &path2) -> QLineF; static void CleanPosition(const VPPiecePtr &piece); auto IsValid(QString &error) const -> bool; @@ -134,6 +139,7 @@ private: bool m_isSelected{false}; bool m_outOfBound{false}; bool m_hasSuperpositionWithPieces{false}; + bool m_invalidPieceGapPosition{false}; quint16 m_copyNumber{1}; diff --git a/src/app/puzzle/layout/vpsheet.cpp b/src/app/puzzle/layout/vpsheet.cpp index 9e776816c..3f68d74f5 100644 --- a/src/app/puzzle/layout/vpsheet.cpp +++ b/src/app/puzzle/layout/vpsheet.cpp @@ -164,6 +164,9 @@ void VPSheetSceneData::PrepareForExport() m_pieceSuperpositionTmp = layout->LayoutSettings().GetWarningSuperpositionOfPieces(); layout->LayoutSettings().SetWarningSuperpositionOfPieces(false); + + m_pieceGapePositionTmp = layout->LayoutSettings().GetWarningPieceGapePosition(); + layout->LayoutSettings().SetWarningPieceGapePosition(false); } RefreshLayout(); @@ -197,6 +200,7 @@ void VPSheetSceneData::CleanAfterExport() layout->LayoutSettings().SetWarningPiecesOutOfBound(m_outOfBoundTmp); layout->LayoutSettings().SetWarningSuperpositionOfPieces(m_pieceSuperpositionTmp); + layout->LayoutSettings().SetWarningPieceGapePosition(m_pieceGapePositionTmp); } RefreshLayout(); @@ -552,6 +556,70 @@ void VPSheet::ValidateSuperpositionOfPieces() const } } +//--------------------------------------------------------------------------------------------------------------------- +void VPSheet::ValidatePieceGapePosition() const +{ + VPLayoutPtr const layout = GetLayout(); + if (layout.isNull()) + { + return; + } + + const qreal pieceGap = layout->LayoutSettings().GetPiecesGap(); + if (pieceGap <= 0) + { + return; + } + + QList const pieces = GetPieces(); + + for (const auto &piece : pieces) + { + if (piece.isNull()) + { + continue; + } + + const bool oldInvalidPieceGapPosition = piece->HasInvalidPieceGapPosition(); + + QVector path1; + CastTo(piece->GetMappedExternalContourPoints(), path1); + path1 = VPPiece::PrepareStickyPath(path1); + bool hasInvalidPieceGapPosition = false; + + for (const auto &p : pieces) + { + if (p.isNull() || piece == p) + { + continue; + } + + QVector path2; + CastTo(p->GetMappedExternalContourPoints(), path2); + path2 = VPPiece::PrepareStickyPath(path2); + + QLineF const distance = VPPiece::ClosestDistance(path1, path2); + + if (distance.length() < pieceGap - accuracyPointOnLine) + { + hasInvalidPieceGapPosition = true; + break; + } + } + + piece->SetHasInvalidPieceGapPosition(hasInvalidPieceGapPosition); + + if (oldInvalidPieceGapPosition != piece->HasInvalidPieceGapPosition()) + { + VPLayoutPtr const layout = GetLayout(); + if (not layout.isNull()) + { + emit layout->PiecePositionValidityChanged(piece); + } + } + } +} + //--------------------------------------------------------------------------------------------------------------------- void VPSheet::ValidatePieceOutOfBound(const VPPiecePtr &piece) const { @@ -699,6 +767,11 @@ void VPSheet::CheckPiecePositionValidity(const VPPiecePtr &piece) const { ValidateSuperpositionOfPieces(); } + + if (layout->LayoutSettings().GetWarningPieceGapePosition()) + { + ValidatePieceGapePosition(); + } } //--------------------------------------------------------------------------------------------------------------------- diff --git a/src/app/puzzle/layout/vpsheet.h b/src/app/puzzle/layout/vpsheet.h index 316190d4d..2c91c81c7 100644 --- a/src/app/puzzle/layout/vpsheet.h +++ b/src/app/puzzle/layout/vpsheet.h @@ -128,6 +128,7 @@ private: bool m_outOfBoundTmp{false}; bool m_pieceSuperpositionTmp{false}; + bool m_pieceGapePositionTmp{false}; void ConnectPiece(VPGraphicsPiece *piece) const; }; @@ -183,6 +184,7 @@ public: void SetTrashSheet(bool newTrashSheet); void ValidateSuperpositionOfPieces() const; + void ValidatePieceGapePosition() const; void ValidatePieceOutOfBound(const VPPiecePtr &piece) const; void ValidatePiecesOutOfBound() const; diff --git a/src/app/puzzle/scene/vpgraphicspiece.cpp b/src/app/puzzle/scene/vpgraphicspiece.cpp index 19c6e2483..e4b71f716 100644 --- a/src/app/puzzle/scene/vpgraphicspiece.cpp +++ b/src/app/puzzle/scene/vpgraphicspiece.cpp @@ -1164,7 +1164,13 @@ auto VPGraphicsPiece::PieceColor() const -> QColor superposition = piece->HasSuperpositionWithPieces(); } - if (outOfBound || superposition) + bool pieceGape = false; + if (layout->LayoutSettings().GetWarningPieceGapePosition()) + { + pieceGape = piece->HasInvalidPieceGapPosition(); + } + + if (outOfBound || superposition || pieceGape) { return VSceneStylesheet::ManualLayoutStyle().PieceErrorColor(); } diff --git a/src/app/puzzle/vpmainwindow.cpp b/src/app/puzzle/vpmainwindow.cpp index 0e73439dc..9f2060d5c 100644 --- a/src/app/puzzle/vpmainwindow.cpp +++ b/src/app/puzzle/vpmainwindow.cpp @@ -1250,6 +1250,8 @@ void VPMainWindow::InitPropertyTabLayout() connect(ui->checkBoxLayoutWarningPiecesSuperposition, &QCheckBox::toggled, this, &VPMainWindow::LayoutWarningPiecesSuperposition_toggled); + connect(ui->checkBoxLayoutWarningPieceGapePosition, &QCheckBox::toggled, this, + &VPMainWindow::LayoutWarningPieceGapePosition_toggled); connect(ui->checkBoxLayoutWarningPiecesOutOfBound, &QCheckBox::toggled, this, &VPMainWindow::LayoutWarningPiecesOutOfBound_toggled); connect(ui->checkBoxCutOnFold, &QCheckBox::toggled, this, &VPMainWindow::LayoutCutOnFold_toggled); @@ -1611,6 +1613,8 @@ void VPMainWindow::SetPropertyTabLayoutData() m_layout->LayoutSettings().GetWarningPiecesOutOfBound()); SetCheckBoxValue(ui->checkBoxLayoutWarningPiecesSuperposition, m_layout->LayoutSettings().GetWarningSuperpositionOfPieces()); + SetCheckBoxValue(ui->checkBoxLayoutWarningPieceGapePosition, + m_layout->LayoutSettings().GetWarningPieceGapePosition()); SetCheckBoxValue(ui->checkBoxSheetStickyEdges, m_layout->LayoutSettings().IsStickyEdges()); SetCheckBoxValue(ui->checkBoxFollowGainline, m_layout->LayoutSettings().GetFollowGrainline()); SetCheckBoxValue(ui->checkBoxTogetherWithNotches, m_layout->LayoutSettings().IsBoundaryTogetherWithNotches()); @@ -2935,7 +2939,8 @@ auto VPMainWindow::DrawTilesScheme(QPrinter *printer, QPainter *painter, const V auto VPMainWindow::AskLayoutIsInvalid(const QList &sheets) -> bool { if (not m_layout->LayoutSettings().GetWarningPiecesOutOfBound() && - not m_layout->LayoutSettings().GetWarningSuperpositionOfPieces()) + not m_layout->LayoutSettings().GetWarningSuperpositionOfPieces() && + not m_layout->LayoutSettings().GetWarningPieceGapePosition()) { return true; } @@ -2944,6 +2949,7 @@ auto VPMainWindow::AskLayoutIsInvalid(const QList &sheets) -> bool { bool outOfBoundChecked = false; bool pieceSuperpositionChecked = false; + bool pieceGapePositionChecked = false; QList const pieces = sheet->GetPieces(); for (const auto &piece : pieces) @@ -2957,6 +2963,11 @@ auto VPMainWindow::AskLayoutIsInvalid(const QList &sheets) -> bool { return false; } + + if (not CheckPieceGapePosition(piece, pieceGapePositionChecked)) + { + return false; + } } } @@ -3023,6 +3034,37 @@ auto VPMainWindow::CheckSuperpositionOfPieces(const VPPiecePtr &piece, bool &pie return true; } +//--------------------------------------------------------------------------------------------------------------------- +auto VPMainWindow::CheckPieceGapePosition(const VPPiecePtr &piece, bool &pieceGapePositionChecked) -> bool +{ + if (m_layout->LayoutSettings().GetWarningPieceGapePosition()) + { + if (not pieceGapePositionChecked && not piece.isNull() && piece->HasInvalidPieceGapPosition()) + { + QMessageBox msgBox(this); + msgBox.setIcon(QMessageBox::Question); + msgBox.setWindowTitle(tr("The layout is invalid.")); + msgBox.setText(tr("The layout is invalid. One or several pieces are closer than minimally allowed. Do you " + "want to continue export?")); + msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No); + msgBox.setDefaultButton(QMessageBox::No); + const int width = 500; + auto *horizontalSpacer = new QSpacerItem(width, 0, QSizePolicy::Minimum, QSizePolicy::Expanding); + auto *layout = qobject_cast(msgBox.layout()); + SCASSERT(layout != nullptr) + layout->addItem(horizontalSpacer, layout->rowCount(), 0, 1, layout->columnCount()); + if (msgBox.exec() == QMessageBox::No) + { + return false; + } + + pieceGapePositionChecked = true; // no need to ask more + } + } + + return true; +} + //--------------------------------------------------------------------------------------------------------------------- void VPMainWindow::PrintLayoutSheets(QPrinter *printer, const QList &sheets) { @@ -4826,6 +4868,25 @@ void VPMainWindow::VerticalScaleChanged(double value) VMainGraphicsView::NewSceneRect(m_graphicsView->scene(), m_graphicsView); } +//--------------------------------------------------------------------------------------------------------------------- +void VPMainWindow::LayoutWarningPieceGapePosition_toggled(bool checked) +{ + if (not m_layout.isNull()) + { + m_layout->LayoutSettings().SetWarningPieceGapePosition(checked); + LayoutWasSaved(false); + if (checked) + { + VPSheetPtr const sheet = m_layout->GetFocusedSheet(); + if (not sheet.isNull()) + { + sheet->ValidatePieceGapePosition(); + } + } + m_graphicsView->RefreshPieces(); + } +} + //--------------------------------------------------------------------------------------------------------------------- void VPMainWindow::LayoutWarningPiecesSuperposition_toggled(bool checked) { diff --git a/src/app/puzzle/vpmainwindow.h b/src/app/puzzle/vpmainwindow.h index 19a8ccc2d..f52aa6330 100644 --- a/src/app/puzzle/vpmainwindow.h +++ b/src/app/puzzle/vpmainwindow.h @@ -293,6 +293,7 @@ private slots: void HorizontalScaleChanged(double value); void VerticalScaleChanged(double value); + void LayoutWarningPieceGapePosition_toggled(bool checked); void LayoutWarningPiecesSuperposition_toggled(bool checked); void LayoutWarningPiecesOutOfBound_toggled(bool checked); void LayoutCutOnFold_toggled(bool checked); @@ -506,6 +507,7 @@ private: auto AskLayoutIsInvalid(const QList &sheets) -> bool; auto CheckPiecesOutOfBound(const VPPiecePtr &piece, bool &outOfBoundChecked) -> bool; auto CheckSuperpositionOfPieces(const VPPiecePtr &piece, bool &pieceSuperpositionChecked) -> bool; + auto CheckPieceGapePosition(const VPPiecePtr &piece, bool &pieceGapePositionChecked) -> bool; void PrintLayoutSheets(QPrinter *printer, const QList &sheets); static auto PrintLayoutSheetPage(QPrinter *printer, QPainter &painter, const VPSheetPtr &sheet) -> bool; diff --git a/src/app/puzzle/vpmainwindow.ui b/src/app/puzzle/vpmainwindow.ui index 39bbb5497..76b3b9fe2 100644 --- a/src/app/puzzle/vpmainwindow.ui +++ b/src/app/puzzle/vpmainwindow.ui @@ -1645,8 +1645,8 @@ 0 0 - 392 - 700 + 378 + 710 @@ -1720,6 +1720,13 @@ + + + + Warning piece gape position + + + @@ -2434,8 +2441,8 @@ + - diff --git a/src/app/puzzle/vpsettings.cpp b/src/app/puzzle/vpsettings.cpp index 4e9d1cfe6..ac74691eb 100644 --- a/src/app/puzzle/vpsettings.cpp +++ b/src/app/puzzle/vpsettings.cpp @@ -63,6 +63,8 @@ Q_GLOBAL_STATIC_WITH_ARGS(const QString, settingLayoutTileShowWatermark, ("layou // NOLINTNEXTLINE Q_GLOBAL_STATIC_WITH_ARGS(const QString, settingLayoutWarningPiecesSuperposition, ("layout/warningPiecesSuperposition"_L1)) +// NOLINTNEXTLINE +Q_GLOBAL_STATIC_WITH_ARGS(const QString, settingLayoutWarningPieceGapePosition, ("layout/warningPieceGapePosition"_L1)) Q_GLOBAL_STATIC_WITH_ARGS(const QString, settingLayoutStickyEdges, ("layout/stickyEdges"_L1)) // NOLINT // NOLINTNEXTLINE Q_GLOBAL_STATIC_WITH_ARGS(const QString, settingLayoutWarningPiecesOutOfBound, ("layout/warningPiecesOutOfBound"_L1)) @@ -292,6 +294,18 @@ auto VPSettings::GetLayoutWarningPiecesSuperposition() const -> bool return value(*settingLayoutWarningPiecesSuperposition, true).toBool(); } +//--------------------------------------------------------------------------------------------------------------------- +void VPSettings::SetLayoutWarningPieceGapePosition(bool value) +{ + setValue(*settingLayoutWarningPieceGapePosition, value); +} + +//--------------------------------------------------------------------------------------------------------------------- +auto VPSettings::GetLayoutWarningPieceGapePosition() const -> bool +{ + return value(*settingLayoutWarningPieceGapePosition, true).toBool(); +} + //--------------------------------------------------------------------------------------------------------------------- void VPSettings::SetLayoutStickyEdges(bool value) { diff --git a/src/app/puzzle/vpsettings.h b/src/app/puzzle/vpsettings.h index 5f8bcfb39..32090f81b 100644 --- a/src/app/puzzle/vpsettings.h +++ b/src/app/puzzle/vpsettings.h @@ -89,6 +89,9 @@ public: void SetLayoutWarningPiecesSuperposition(bool value); auto GetLayoutWarningPiecesSuperposition() const -> bool; + void SetLayoutWarningPieceGapePosition(bool value); + auto GetLayoutWarningPieceGapePosition() const -> bool; + void SetLayoutStickyEdges(bool value); auto GetLayoutStickyEdges() const -> bool; diff --git a/src/app/puzzle/xml/vplayoutfilereader.cpp b/src/app/puzzle/xml/vplayoutfilereader.cpp index 5c36f48e4..7da06e962 100644 --- a/src/app/puzzle/xml/vplayoutfilereader.cpp +++ b/src/app/puzzle/xml/vplayoutfilereader.cpp @@ -333,6 +333,7 @@ void VPLayoutFileReader::ReadControl(const VPLayoutPtr &layout) QXmlStreamAttributes const attribs = attributes(); layout->LayoutSettings().SetWarningSuperpositionOfPieces( ReadAttributeBool(attribs, ML::AttrWarningSuperposition, trueStr)); + layout->LayoutSettings().SetWarningPieceGapePosition(ReadAttributeBool(attribs, ML::AttrWarningPieceGape, trueStr)); layout->LayoutSettings().SetWarningPiecesOutOfBound(ReadAttributeBool(attribs, ML::AttrWarningOutOfBound, trueStr)); layout->LayoutSettings().SetStickyEdges(ReadAttributeBool(attribs, ML::AttrStickyEdges, trueStr)); layout->LayoutSettings().SetPiecesGap(qMax(ReadAttributeDouble(attribs, ML::AttrPiecesGap, QChar('0')), 0.0)); diff --git a/src/app/puzzle/xml/vplayoutfilewriter.cpp b/src/app/puzzle/xml/vplayoutfilewriter.cpp index c79008192..56824754e 100644 --- a/src/app/puzzle/xml/vplayoutfilewriter.cpp +++ b/src/app/puzzle/xml/vplayoutfilewriter.cpp @@ -172,6 +172,7 @@ void VPLayoutFileWriter::WriteLayoutProperties(const VPLayoutPtr &layout) writeStartElement(ML::TagControl); SetAttribute(ML::AttrWarningSuperposition, layout->LayoutSettings().GetWarningSuperpositionOfPieces()); SetAttribute(ML::AttrWarningOutOfBound, layout->LayoutSettings().GetWarningPiecesOutOfBound()); + SetAttribute(ML::AttrWarningPieceGape, layout->LayoutSettings().GetWarningPieceGapePosition()); SetAttribute(ML::AttrStickyEdges, layout->LayoutSettings().IsStickyEdges()); SetAttribute(ML::AttrPiecesGap, layout->LayoutSettings().GetPiecesGap()); SetAttribute(ML::AttrFollowGrainline, layout->LayoutSettings().GetFollowGrainline()); diff --git a/src/app/puzzle/xml/vplayoutliterals.cpp b/src/app/puzzle/xml/vplayoutliterals.cpp index 156eb3b73..7fb0fd612 100644 --- a/src/app/puzzle/xml/vplayoutliterals.cpp +++ b/src/app/puzzle/xml/vplayoutliterals.cpp @@ -71,6 +71,7 @@ const QString TagMirrorLine = QStringLiteral("mirrorLine"); // NOLINT(ce const QString AttrWarningSuperposition = QStringLiteral("warningSuperposition"); // NOLINT(cert-err58-cpp) const QString AttrWarningOutOfBound = QStringLiteral("warningOutOfBound"); // NOLINT(cert-err58-cpp) +const QString AttrWarningPieceGape = QStringLiteral("warningPieceGape"); // NOLINT(cert-err58-cpp) const QString AttrStickyEdges = QStringLiteral("stickyEdges"); // NOLINT(cert-err58-cpp) const QString AttrPiecesGap = QStringLiteral("piecesGap"); // NOLINT(cert-err58-cpp) const QString AttrVisible = QStringLiteral("visible"); // NOLINT(cert-err58-cpp) diff --git a/src/app/puzzle/xml/vplayoutliterals.h b/src/app/puzzle/xml/vplayoutliterals.h index 533e8eb2b..0a555dc95 100644 --- a/src/app/puzzle/xml/vplayoutliterals.h +++ b/src/app/puzzle/xml/vplayoutliterals.h @@ -70,6 +70,7 @@ extern const QString TagMirrorLine; extern const QString AttrWarningSuperposition; extern const QString AttrWarningOutOfBound; +extern const QString AttrWarningPieceGape; extern const QString AttrStickyEdges; extern const QString AttrPiecesGap; extern const QString AttrVisible; diff --git a/src/libs/ifc/schema/layout/v0.1.9.xsd b/src/libs/ifc/schema/layout/v0.1.9.xsd index 40f4172a8..24eb26e08 100644 --- a/src/libs/ifc/schema/layout/v0.1.9.xsd +++ b/src/libs/ifc/schema/layout/v0.1.9.xsd @@ -12,6 +12,7 @@ +