Compare commits

...

7 Commits

Author SHA1 Message Date
Roman Telezhynskyi 7de604a63b Use job_group. 2024-04-22 19:58:33 +03:00
Roman Telezhynskyi ce1634e1ab Fix crash when remove pieces. 2024-04-22 18:13:43 +03:00
Roman Telezhynskyi 6eb702b778 Refactoring.
Since Qt 6.7 we can start using enum QIcon::ThemeIcon.
2024-04-22 18:13:43 +03:00
Roman Telezhynskyi ed4f2945da Show a piece position status in Property tab. 2024-04-22 18:13:43 +03:00
Roman Telezhynskyi 537efbeaa8 Move piece position validation to separate thread. 2024-04-22 18:13:42 +03:00
Roman Telezhynskyi a8a75f358a Skip commits. 2024-04-22 18:13:42 +03:00
Roman Telezhynskyi 4a97ca14bf Refactoring. 2024-04-18 16:56:25 +03:00
33 changed files with 1210 additions and 408 deletions

View File

@ -19,6 +19,10 @@ branches:
- develop
- master
skip_commits:
files:
- ".cirrus.yml"
# Do not build on tags (GitHub and BitBucket)
skip_tags: true
@ -43,7 +47,30 @@ environment:
VALENTINA_VERSION: 0_7_52
matrix:
- job_name: Windows_Qt_6_7_(MSVC_x64)
job_group: 'Windows (qbs)'
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022
COMPILER: msvc
QT: Qt\6.7\msvc2019_64
QT_VERSION: Qt6_7
BUILD_SYSTEM: "qbs"
QMAKE: qmake.exe
ENABLE_PCH: true
MSVC_PATH: "C:\\Program Files\\Microsoft Visual Studio\\2022\\Community\\VC\\Tools\\MSVC\\14.39.33519\\bin\\Hostx64\\x64"
VSINSTALLDIR: "C:\\Program Files\\Microsoft Visual Studio\\2022\\Community\\"
ARCH: x64
PYTHON: "C:\\Python311-x64"
TARGET_PLATFORM: "Windows10+"
CHOCOLATEY_PACKAGES: false
WINDEPLOYQT_BIN_PATH: "undefined"
WINDEPLOYQT_COMPILER_RUNTIME: "true"
WINDEPLOYQT_NO_COMPILER_RUNTIME: "false"
DEPLOY: true
RUN_TESTS: true
WITH_CRASH_REPORTING: True
# - job_name: Windows_Qt_6_7_(GCC_x64)
# job_group: 'Windows (qbs)'
# APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022
# COMPILER: mingw
# COMPILER_CPPSTD: gnu17
@ -68,6 +95,7 @@ environment:
# WITH_CRASH_REPORTING: False
- job_name: MacOS_12_Qt_5_15 (qbs, multibundle)
job_group: 'MacOS_12 (qbs)'
APPVEYOR_BUILD_WORKER_IMAGE: macos-monterey
COMPILER: clang
QT: Qt/5.15/clang_64
@ -81,6 +109,7 @@ environment:
DEPLOY: true
- job_name: MacOS_12_Qt_5_15 (qbs, singlebundle)
job_group: 'MacOS_12 (qbs)'
APPVEYOR_BUILD_WORKER_IMAGE: macos-monterey
COMPILER: clang
QT: Qt/5.15/clang_64
@ -94,6 +123,7 @@ environment:
DEPLOY: true
- job_name: MacOS_14_Qt_6_6 (multibundle)
job_group: 'MacOS_14'
APPVEYOR_BUILD_WORKER_IMAGE: macos-sonoma
COMPILER: clang
QT: Qt/6.6/macos
@ -107,6 +137,7 @@ environment:
DEPLOY: true
- job_name: MacOS_14_Qt_6_6 (singlebundle)
job_group: 'MacOS_14'
APPVEYOR_BUILD_WORKER_IMAGE: macos-sonoma
COMPILER: clang
QT: Qt/6.6/macos
@ -119,28 +150,8 @@ environment:
MULTI_BUNDLE: false
DEPLOY: true
- job_name: Windows_Qt_6_7_(MSVC_x64)
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022
COMPILER: msvc
QT: Qt\6.7\msvc2019_64
QT_VERSION: Qt6_7
BUILD_SYSTEM: "qbs"
QMAKE: qmake.exe
ENABLE_PCH: true
MSVC_PATH: "C:\\Program Files\\Microsoft Visual Studio\\2022\\Community\\VC\\Tools\\MSVC\\14.30.30705\\bin\\Hostx64\\x64"
VSINSTALLDIR: "C:\\Program Files\\Microsoft Visual Studio\\2022\\Community\\"
ARCH: x64
PYTHON: "C:\\Python311-x64"
TARGET_PLATFORM: "Windows10+"
CHOCOLATEY_PACKAGES: false
WINDEPLOYQT_BIN_PATH: "undefined"
WINDEPLOYQT_COMPILER_RUNTIME: "true"
WINDEPLOYQT_NO_COMPILER_RUNTIME: "false"
DEPLOY: true
RUN_TESTS: true
WITH_CRASH_REPORTING: True
- job_name: Windows_Qt_5_15_(qbs_GCC_x86)
job_group: 'Windows (qbs)'
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
COMPILER: mingw
COMPILER_CPPSTD: gnu17
@ -164,6 +175,7 @@ environment:
WITH_CRASH_REPORTING: False
- job_name: Windows_Qt_5_15_(make_GCC_x86)
job_group: 'Windows (make)'
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
COMPILER: mingw
QT: Qt\5.15\mingw81_32
@ -176,6 +188,7 @@ environment:
DEPLOY: false
- job_name: Windows_Qt_5_15_(qbs_GCC_x64)
job_group: 'Windows (qbs)'
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
COMPILER: mingw
COMPILER_CPPSTD: gnu17
@ -199,6 +212,7 @@ environment:
WITH_CRASH_REPORTING: False
- job_name: Windows_Qt_5_15_(qbs_MSVC_x64)
job_group: 'Windows (qbs)'
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
COMPILER: msvc
QT: Qt\5.15\msvc2019_64
@ -220,6 +234,7 @@ environment:
WITH_CRASH_REPORTING: False
- job_name: Windows_Qt_5_15_(make_GCC_x64)
job_group: 'Windows (make)'
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
COMPILER: mingw
QT: Qt\5.15\mingw81_64
@ -232,6 +247,7 @@ environment:
DEPLOY: false
- job_name: Windows_Qt_5_15_(nmake_MSVC_x64)
job_group: 'Windows (make)'
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
COMPILER: msvc
QT: Qt\5.15\msvc2019_64
@ -243,6 +259,7 @@ environment:
DEPLOY: false
- job_name: MacOS_12_Qt_5_15 (make)
job_group: 'MacOS (make)'
APPVEYOR_BUILD_WORKER_IMAGE: macos-monterey
COMPILER: clang
QT: Qt/5.15/clang_64
@ -292,11 +309,7 @@ for:
-
matrix:
only:
# - job_name: Windows_Qt_6_7_(GCC_x64)
- job_name: Windows_Qt_6_7_(MSVC_x64)
- job_name: Windows_Qt_5_15_(qbs_GCC_x64)
- job_name: Windows_Qt_5_15_(qbs_MSVC_x64)
- job_name: Windows_Qt_5_15_(qbs_GCC_x86)
- job_group: 'Windows (qbs)'
# clone directory
clone_folder: c:\projects\valentina
@ -434,9 +447,7 @@ for:
-
matrix:
only:
- job_name: Windows_Qt_5_15_(make_GCC_x86)
- job_name: Windows_Qt_5_15_(make_GCC_x64)
- job_name: Windows_Qt_5_15_(nmake_MSVC_x64)
- job_group: 'Windows (make)'
# clone directory
clone_folder: c:\projects\valentina
@ -525,8 +536,7 @@ for:
-
matrix:
only:
- job_name: MacOS_14_Qt_6_6 (multibundle)
- job_name: MacOS_14_Qt_6_6 (singlebundle)
- job_group: 'MacOS_14'
environment:
CONAN_USER_HOME: /Users/appveyor
@ -727,8 +737,7 @@ for:
-
matrix:
only:
- job_name: MacOS_12_Qt_5_15 (qbs, multibundle)
- job_name: MacOS_12_Qt_5_15 (qbs, singlebundle)
- job_group: 'MacOS_12 (qbs)'
environment:
CONAN_USER_HOME: /Users/appveyor
@ -927,7 +936,7 @@ for:
-
matrix:
only:
- job_name: MacOS_12_Qt_5_15 (make)
- job_group: 'MacOS (make)'
init:
- find /Applications -maxdepth 1 -type d -name 'Xcode*.app'

View File

@ -276,7 +276,7 @@ auto VPLayout::AddSheet(const VPSheetPtr &sheet) -> VPSheetPtr
if (not sheet.isNull() && GetSheet(sheet->Uuid()).isNull())
{
m_sheets.append(sheet);
connect(this, &VPLayout::PieceTransformationChanged, sheet.data(), &VPSheet::CheckPiecePositionValidity);
connect(this, &VPLayout::PieceTransformationChanged, sheet.data(), &VPSheet::CheckPiecesPositionValidity);
}
return sheet;
}
@ -328,7 +328,7 @@ void VPLayout::SetFocusedSheet(const VPSheetPtr &focusedSheet)
m_focusedSheet = focusedSheet.isNull() ? m_sheets.constFirst() : focusedSheet;
}
CheckPiecesPositionValidity(m_focusedSheet);
m_focusedSheet->CheckPiecesPositionValidity();
emit ActiveSheetChanged(m_focusedSheet);
}
@ -427,30 +427,9 @@ void VPLayout::CheckPiecesPositionValidity() const
{
for (const auto &sheet : m_sheets)
{
CheckPiecesPositionValidity(sheet);
}
}
//---------------------------------------------------------------------------------------------------------------------
void VPLayout::CheckPiecesPositionValidity(const VPSheetPtr &sheet) const
{
if (not sheet.isNull())
{
const VPLayoutSettings &settings = LayoutSettings();
if (settings.GetWarningPiecesOutOfBound())
if (not sheet.isNull())
{
sheet->ValidatePiecesOutOfBound();
}
if (settings.GetWarningSuperpositionOfPieces())
{
sheet->ValidateSuperpositionOfPieces();
}
if (settings.GetWarningPieceGapePosition())
{
sheet->ValidatePieceGapePosition();
sheet->CheckPiecesPositionValidity();
}
}
}

View File

@ -91,7 +91,6 @@ public:
void Clear();
void CheckPiecesPositionValidity() const;
void CheckPiecesPositionValidity(const VPSheetPtr &sheet) const;
auto TileFactory() const -> QSharedPointer<VPTileFactory>;
void SetTileFactory(const QSharedPointer<VPTileFactory> &newTileFactory);

View File

@ -62,7 +62,7 @@ namespace
{
constexpr qreal minStickyDistance = MmToPixel(3.);
constexpr qreal maxStickyDistance = MmToPixel(15.);
constexpr qreal stickyShift = MmToPixel(1.);
constexpr qreal stickyShift = MmToPixel(5.);
//---------------------------------------------------------------------------------------------------------------------
auto CutEdge(const QLineF &edge) -> QVector<QPointF>
@ -440,24 +440,15 @@ auto VPPiece::PrepareStickyPath(const QVector<QPointF> &path) -> QVector<QPointF
//---------------------------------------------------------------------------------------------------------------------
auto VPPiece::ClosestDistance(const QVector<QPointF> &path1, const QVector<QPointF> &path2) -> QLineF
{
std::function<QLineF(const QPointF &)> const DistanceFunc = [path2](const QPointF &p1)
const int maxThreads = QThread::idealThreadCount();
QVector<QVector<QPointF>> path1Chunks;
path1Chunks.reserve(maxThreads);
const vsizetype chunkSize = (path1.size() + maxThreads - 1) / maxThreads; // Round up
for (vsizetype i = 0; i < path1.size(); i += chunkSize)
{
qreal minLocalDistance = std::numeric_limits<qreal>::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;
};
path1Chunks.append(path1.mid(i, chunkSize));
}
std::function<void(QLineF &, const QLineF &)> const ReduceFunc = [](QLineF &result, const QLineF &next)
{
@ -469,7 +460,29 @@ auto VPPiece::ClosestDistance(const QVector<QPointF> &path1, const QVector<QPoin
}
};
return QtConcurrent::blockingMappedReduced<QLineF>(path1, DistanceFunc, ReduceFunc);
auto CalculateClosestDistanceForChunk = [&](const QVector<QPointF> &chunk) -> QLineF
{
qreal minLocalDistance = std::numeric_limits<qreal>::max();
QLineF localClosestDistance;
for (const auto &c : chunk)
{
for (const auto &p2 : path2)
{
QLineF const d(c, p2);
qreal const length = d.length();
if (length < minLocalDistance)
{
minLocalDistance = length;
localClosestDistance = d;
}
}
}
return localClosestDistance;
};
return QtConcurrent::blockingMappedReduced<QLineF>(path1Chunks, CalculateClosestDistanceForChunk, ReduceFunc);
}
//---------------------------------------------------------------------------------------------------------------------

View File

@ -38,6 +38,205 @@
#include "vplayout.h"
#include "vppiece.h"
#include <QtConcurrent>
namespace
{
struct VSheetPiece
{
QString m_id{};
bool m_showFullPiece{false};
QLineF m_seamMirrorLine{};
QLineF m_seamAllowanceMirrorLine{};
QVector<QPointF> m_externalContourPoints{};
};
struct VPiecesValidationData
{
bool m_warnPiecesOutOfBound{false};
bool m_warnSuperpositionOfPieces{false};
bool m_warnPieceGapePosition{false};
bool m_cutOnFold{false};
QRectF m_sheetRect{};
qreal m_pieceGap{0};
QVector<VSheetPiece> m_pieces{};
};
//---------------------------------------------------------------------------------------------------------------------
void ValidatePiecesOutOfBound(const VPiecesValidationData &data, QHash<QString, VPiecePositionValidity> &validations)
{
for (const auto &piece : data.m_pieces)
{
VPiecePositionValidity validation = validations.value(piece.m_id);
if (data.m_cutOnFold && not piece.m_showFullPiece && !piece.m_seamMirrorLine.isNull())
{
QLineF const foldLine = data.m_sheetRect.width() >= data.m_sheetRect.height()
? QLineF(data.m_sheetRect.topLeft(), data.m_sheetRect.topRight())
: QLineF(data.m_sheetRect.topRight(), data.m_sheetRect.bottomRight());
validation.m_outOfBound =
not VGObject::IsLineSegmentOnLineSegment(foldLine, piece.m_seamAllowanceMirrorLine, MmToPixel(0.5));
}
else
{
QRectF const pieceRect = VLayoutPiece::BoundingRect(piece.m_externalContourPoints);
validation.m_outOfBound = not data.m_sheetRect.contains(pieceRect);
}
validations.insert(piece.m_id, validation);
}
}
//---------------------------------------------------------------------------------------------------------------------
void ValidateSuperpositionOfPieces(const VPiecesValidationData &data,
QHash<QString, VPiecePositionValidity> &validations)
{
QSet<QString> invalidPieces;
invalidPieces.reserve(data.m_pieces.size());
for (const auto &piece : data.m_pieces)
{
if (invalidPieces.contains(piece.m_id))
{
continue;
}
bool hasSuperposition = false;
VSheetPiece invalidPiece;
for (const auto &p : data.m_pieces)
{
if (piece.m_id == p.m_id)
{
continue;
}
if (VPPiece::PathsSuperposition(piece.m_externalContourPoints, p.m_externalContourPoints))
{
hasSuperposition = true;
invalidPiece = p;
break;
}
}
auto UpdateValidity = [&validations, hasSuperposition, &invalidPieces](const QString &id)
{
VPiecePositionValidity validation = validations.value(id);
validation.m_superposition = hasSuperposition;
validations.insert(id, validation);
if (hasSuperposition)
{
invalidPieces.insert(id);
}
};
UpdateValidity(piece.m_id);
if (!invalidPiece.m_id.isEmpty())
{
UpdateValidity(invalidPiece.m_id);
}
}
}
//---------------------------------------------------------------------------------------------------------------------
void ValidatePiecesGapePosition(const VPiecesValidationData &data, QHash<QString, VPiecePositionValidity> &validations)
{
if (data.m_pieceGap <= 0)
{
return;
}
QSet<QString> invalidPieces;
invalidPieces.reserve(data.m_pieces.size());
for (const auto &piece : data.m_pieces)
{
if (invalidPieces.contains(piece.m_id))
{
continue;
}
QRectF const path1Rect = VLayoutPiece::BoundingRect(piece.m_externalContourPoints)
.adjusted(-data.m_pieceGap, -data.m_pieceGap, data.m_pieceGap, data.m_pieceGap);
QVector<QPointF> const path1 = VPPiece::PrepareStickyPath(piece.m_externalContourPoints);
bool hasInvalidPieceGapPosition = false;
VSheetPiece invalidPiece;
for (const auto &p : data.m_pieces)
{
if (piece.m_id == p.m_id)
{
continue;
}
QRectF const path2Rect =
VLayoutPiece::BoundingRect(p.m_externalContourPoints)
.adjusted(-data.m_pieceGap, -data.m_pieceGap, data.m_pieceGap, data.m_pieceGap);
if (!path1Rect.intersects(path2Rect) && !path1Rect.contains(path2Rect) && !path2Rect.contains(path1Rect))
{
continue;
}
QVector<QPointF> const path2 = VPPiece::PrepareStickyPath(p.m_externalContourPoints);
QLineF const distance = VPPiece::ClosestDistance(path1, path2);
if (distance.length() < data.m_pieceGap - accuracyPointOnLine)
{
hasInvalidPieceGapPosition = true;
invalidPiece = p;
break;
}
}
auto UpdateValidity = [&validations, hasInvalidPieceGapPosition, &invalidPieces](const QString &id)
{
VPiecePositionValidity validation = validations.value(id);
validation.m_gap = hasInvalidPieceGapPosition;
validations.insert(id, validation);
if (hasInvalidPieceGapPosition)
{
invalidPieces.insert(id);
}
};
UpdateValidity(piece.m_id);
if (!invalidPiece.m_id.isEmpty())
{
UpdateValidity(invalidPiece.m_id);
}
}
}
//---------------------------------------------------------------------------------------------------------------------
auto ValidatePiecesPositions(const VPiecesValidationData &data) -> QHash<QString, VPiecePositionValidity>
{
QHash<QString, VPiecePositionValidity> validations;
if (data.m_warnPiecesOutOfBound)
{
ValidatePiecesOutOfBound(data, validations);
}
if (data.m_warnSuperpositionOfPieces)
{
ValidateSuperpositionOfPieces(data, validations);
}
if (data.m_warnPieceGapePosition)
{
ValidatePiecesGapePosition(data, validations);
}
return validations;
}
} // namespace
// VPSheetSceneData
//---------------------------------------------------------------------------------------------------------------------
VPSheetSceneData::VPSheetSceneData(const VPLayoutPtr &layout, const QUuid &sheetUuid)
@ -339,7 +538,8 @@ void VPSheetSceneData::ConnectPiece(VPGraphicsPiece *piece) const
VPSheet::VPSheet(const VPLayoutPtr &layout, QObject *parent)
: QObject(parent),
m_layout(layout),
m_sceneData(QSharedPointer<VPSheetSceneData>::create(layout, Uuid()))
m_sceneData(QSharedPointer<VPSheetSceneData>::create(layout, Uuid())),
m_validityWatcher(new QFutureWatcher<QHash<QString, VPiecePositionValidity>>(this))
{
SCASSERT(not layout.isNull())
@ -347,10 +547,16 @@ VPSheet::VPSheet(const VPLayoutPtr &layout, QObject *parent)
SetIgnoreMargins(settings->GetLayoutSheetIgnoreMargins());
SetSheetMargins(settings->GetLayoutSheetMargins());
SetSheetSize(QSizeF(settings->GetLayoutSheetPaperWidth(), settings->GetLayoutSheetPaperHeight()));
connect(m_validityWatcher, &QFutureWatcher<QHash<QString, VPiecePositionValidity>>::finished, this,
&VPSheet::UpdatePiecesValidity);
}
//---------------------------------------------------------------------------------------------------------------------
VPSheet::~VPSheet() = default;
VPSheet::~VPSheet()
{
m_validityWatcher->cancel();
}
//---------------------------------------------------------------------------------------------------------------------
auto VPSheet::GetLayout() const -> VPLayoutPtr
@ -508,171 +714,6 @@ void VPSheet::SetTrashSheet(bool newTrashSheet)
m_trashSheet = newTrashSheet;
}
//---------------------------------------------------------------------------------------------------------------------
void VPSheet::ValidateSuperpositionOfPieces() const
{
QList<VPPiecePtr> const pieces = GetPieces();
for (const auto &piece : pieces)
{
if (piece.isNull() || piece->OutOfBound())
{
continue;
}
const bool oldSuperpositionOfPieces = piece->HasSuperpositionWithPieces();
QVector<QPointF> path1;
CastTo(piece->GetMappedExternalContourPoints(), path1);
bool hasSuperposition = false;
for (const auto &p : pieces)
{
if (p.isNull() || piece == p)
{
continue;
}
QVector<QPointF> path2;
CastTo(p->GetMappedExternalContourPoints(), path2);
bool const superposition = VPPiece::PathsSuperposition(path1, path2);
if (superposition)
{
hasSuperposition = superposition;
break;
}
}
piece->SetHasSuperpositionWithPieces(hasSuperposition);
if (oldSuperpositionOfPieces != piece->HasSuperpositionWithPieces())
{
VPLayoutPtr const layout = GetLayout();
if (not layout.isNull())
{
emit layout->PiecePositionValidityChanged(piece);
}
}
}
}
//---------------------------------------------------------------------------------------------------------------------
void VPSheet::ValidatePieceGapePosition(const VPPiecePtr &piece) const
{
VPLayoutPtr const layout = GetLayout();
if (layout.isNull())
{
return;
}
const qreal pieceGap = layout->LayoutSettings().GetPiecesGap();
if (pieceGap <= 0)
{
return;
}
if (piece.isNull() || piece->HasSuperpositionWithPieces() || piece->OutOfBound())
{
return;
}
const bool oldInvalidPieceGapPosition = piece->HasInvalidPieceGapPosition();
QVector<QPointF> path1;
CastTo(piece->GetMappedExternalContourPoints(), path1);
path1 = VPPiece::PrepareStickyPath(path1);
bool hasInvalidPieceGapPosition = false;
QList<VPPiecePtr> const pieces = GetPieces();
for (const auto &p : pieces)
{
if (p.isNull() || piece == p)
{
continue;
}
QVector<QPointF> 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::ValidatePieceGapePosition() const
{
QList<VPPiecePtr> const pieces = GetPieces();
for (const auto &piece : pieces)
{
ValidatePieceGapePosition(piece);
}
}
//---------------------------------------------------------------------------------------------------------------------
void VPSheet::ValidatePieceOutOfBound(const VPPiecePtr &piece) const
{
if (piece.isNull())
{
return;
}
const bool oldOutOfBound = piece->OutOfBound();
QRectF const sheetRect = GetMarginsRect();
VPLayoutPtr const layout = GetLayout();
if (not layout.isNull() && layout->LayoutSettings().IsCutOnFold() && not piece->IsShowFullPiece() &&
!piece->GetSeamMirrorLine().isNull())
{
QLineF const foldLine = sheetRect.width() >= sheetRect.height()
? QLineF(sheetRect.topLeft(), sheetRect.topRight())
: QLineF(sheetRect.topRight(), sheetRect.bottomRight());
piece->SetOutOfBound(not VGObject::IsLineSegmentOnLineSegment(
foldLine, piece->GetMappedSeamAllowanceMirrorLine(), MmToPixel(0.5)));
}
else
{
QRectF const pieceRect = piece->MappedDetailBoundingRect();
piece->SetOutOfBound(not sheetRect.contains(pieceRect));
}
if (oldOutOfBound != piece->OutOfBound())
{
if (not layout.isNull())
{
emit layout->PiecePositionValidityChanged(piece);
}
}
}
//---------------------------------------------------------------------------------------------------------------------
void VPSheet::ValidatePiecesOutOfBound() const
{
QList<VPPiecePtr> const pieces = GetPieces();
for (const auto &piece : pieces)
{
ValidatePieceOutOfBound(piece);
}
}
//---------------------------------------------------------------------------------------------------------------------
auto VPSheet::GetSheetRect() const -> QRectF
{
@ -752,32 +793,91 @@ void VPSheet::RemoveUnusedLength()
}
//---------------------------------------------------------------------------------------------------------------------
void VPSheet::CheckPiecePositionValidity(const VPPiecePtr &piece) const
void VPSheet::CheckPiecesPositionValidity() const
{
if (m_validityWatcher->isFinished())
{
VPLayoutPtr const layout = GetLayout();
if (layout.isNull())
{
return;
}
VPiecesValidationData data;
data.m_warnPiecesOutOfBound = layout->LayoutSettings().GetWarningPiecesOutOfBound();
data.m_warnSuperpositionOfPieces = layout->LayoutSettings().GetWarningSuperpositionOfPieces();
data.m_warnPieceGapePosition = layout->LayoutSettings().GetWarningPieceGapePosition();
data.m_cutOnFold = layout->LayoutSettings().IsCutOnFold();
data.m_sheetRect = GetMarginsRect();
data.m_pieceGap = layout->LayoutSettings().GetPiecesGap();
QList<VPPiecePtr> const pieces = GetPieces();
QVector<VSheetPiece> sheetPieces;
sheetPieces.reserve(pieces.size());
for (const auto &piece : pieces)
{
VSheetPiece data;
data.m_showFullPiece = piece->IsShowFullPiece();
data.m_id = piece->GetUniqueID();
data.m_seamMirrorLine = piece->GetMappedSeamMirrorLine();
data.m_seamAllowanceMirrorLine = piece->GetMappedSeamAllowanceMirrorLine();
QVector<QPointF> points;
CastTo(piece->GetMappedExternalContourPoints(), points);
data.m_externalContourPoints = points;
sheetPieces.append(data);
}
data.m_pieces = sheetPieces;
m_validationStale = false;
m_validityWatcher->setFuture(QtConcurrent::run([data]() { return ValidatePiecesPositions(data); }));
}
else
{
m_validationStale = true;
}
}
//---------------------------------------------------------------------------------------------------------------------
void VPSheet::UpdatePiecesValidity()
{
QHash<QString, VPiecePositionValidity> const newValidations = m_validityWatcher->future().result();
QList<VPPiecePtr> const pieces = GetPieces();
QHash<QString, VPPiecePtr> sortedPieces;
sortedPieces.reserve(pieces.size());
for (const auto &piece : pieces)
{
sortedPieces.insert(piece->GetUniqueID(), piece);
}
VPLayoutPtr const layout = GetLayout();
if (layout.isNull())
{
return;
}
if (QList<VPPiecePtr> const pieces = GetPieces(); piece.isNull() || not pieces.contains(piece))
for (auto i = newValidations.cbegin(), end = newValidations.cend(); i != end; ++i)
{
return;
if (sortedPieces.contains(i.key()))
{
VPPiecePtr const piece = sortedPieces.value(i.key());
piece->SetOutOfBound(i.value().m_outOfBound);
piece->SetHasSuperpositionWithPieces(i.value().m_superposition);
piece->SetHasInvalidPieceGapPosition(i.value().m_gap);
emit layout->PiecePositionValidityChanged(piece);
}
}
if (layout->LayoutSettings().GetWarningPiecesOutOfBound())
if (m_validationStale)
{
ValidatePieceOutOfBound(piece);
}
if (layout->LayoutSettings().GetWarningSuperpositionOfPieces())
{
ValidateSuperpositionOfPieces();
}
if (layout->LayoutSettings().GetWarningPieceGapePosition())
{
ValidatePieceGapePosition(piece);
m_validationStale = false;
CheckPiecesPositionValidity();
}
}

View File

@ -29,6 +29,7 @@
#define VPSHEET_H
#include <QComboBox>
#include <QFutureWatcher>
#include <QList>
#include <QMarginsF>
#include <QPageLayout>
@ -50,6 +51,13 @@ class VPGraphicsSheet;
class VLayoutPiece;
class QGraphicsItem;
struct VPiecePositionValidity
{
bool m_outOfBound{false};
bool m_superposition{false};
bool m_gap{false};
};
class VPSheetSceneData
{
public:
@ -183,12 +191,6 @@ public:
auto TrashSheet() const -> bool;
void SetTrashSheet(bool newTrashSheet);
void ValidateSuperpositionOfPieces() const;
void ValidatePieceGapePosition(const VPPiecePtr &piece) const;
void ValidatePieceGapePosition() const;
void ValidatePieceOutOfBound(const VPPiecePtr &piece) const;
void ValidatePiecesOutOfBound() const;
auto GetSheetRect() const -> QRectF;
auto GetMarginsRect() const -> QRectF;
@ -283,7 +285,10 @@ public:
auto GetSheetOrientation() const -> QPageLayout::Orientation;
public slots:
void CheckPiecePositionValidity(const VPPiecePtr &piece) const;
void CheckPiecesPositionValidity() const;
private slots:
void UpdatePiecesValidity();
private:
Q_DISABLE_COPY_MOVE(VPSheet) // NOLINT
@ -316,6 +321,9 @@ private:
QSharedPointer<VPSheetSceneData> m_sceneData{nullptr};
QFutureWatcher<QHash<QString, VPiecePositionValidity>> *m_validityWatcher;
mutable bool m_validationStale{false};
auto SheetUnits() const -> Unit;
};

View File

@ -38,6 +38,7 @@
#include "../layout/vplayout.h"
#include "../layout/vppiece.h"
#include "../layout/vpsheet.h"
#include "../vmisc/theme/themeDef.h"
#include "../vwidgets/vmaingraphicsscene.h"
#include "undocommands/vpundopiecezvaluemove.h"
#include "vpgraphicspiece.h"
@ -348,7 +349,7 @@ void VPMainGraphicsView::contextMenuEvent(QContextMenuEvent *event)
restoreOriginAction->setShortcut(*restoreOriginShortcut);
restoreOriginAction->setEnabled(not sheet.isNull() && sheet->TransformationOrigin().custom);
QAction *removeSheetAction = menu.addAction(QIcon::fromTheme(QStringLiteral("edit-delete")), tr("Remove sheet"));
QAction *removeSheetAction = menu.addAction(FromTheme(VThemeIcon::EditDelete), tr("Remove sheet"));
removeSheetAction->setEnabled(not sheet.isNull() && layout->GetSheets().size() > 1);
QAction *selectedAction = menu.exec(event->globalPos());
@ -638,6 +639,10 @@ void VPMainGraphicsView::RemovePiece() const
}
const QList<VPGraphicsPiece *> &graphicsPieces = sheet->SceneData()->GraphicsPieces();
QVector<VPUndoMovePieceOnSheet *> commands;
commands.reserve(graphicsPieces.size());
for (auto *graphicsPiece : graphicsPieces)
{
VPPiecePtr const piece = graphicsPiece->GetPiece();
@ -645,17 +650,26 @@ void VPMainGraphicsView::RemovePiece() const
if (not piece.isNull() && piece->IsSelected())
{
piece->SetSelected(false);
emit layout->PieceSelectionChanged(piece);
VPLayoutPtr const layout = m_layout.toStrongRef();
if (not layout.isNull())
{
emit layout->PieceSelectionChanged(piece);
auto *command = new VPUndoMovePieceOnSheet(VPSheetPtr(), piece);
layout->UndoStack()->push(command);
}
commands.append(new VPUndoMovePieceOnSheet(VPSheetPtr(), piece));
}
}
if (commands.size() > 1)
{
layout->UndoStack()->beginMacro(tr("Remove pieces"));
}
for (auto *command : commands)
{
layout->UndoStack()->push(command);
}
if (commands.size() > 1)
{
layout->UndoStack()->endMacro();
}
}
//---------------------------------------------------------------------------------------------------------------------

View File

@ -76,9 +76,26 @@ void VPUndoMovePieceOnSheet::undo()
piece->SetSheet(sourceSheet);
piece->SetSelected(false);
if ((m_followGrainline || piece->IsFollowGrainline()) && !sourceSheet.isNull())
{
QT_WARNING_PUSH
QT_WARNING_DISABLE_GCC("-Wnoexcept")
VPTransformationOrigon origin;
origin.custom = true;
QT_WARNING_POP
piece->RotateToGrainline(origin);
}
if (not layout.isNull())
{
emit layout->PieceSheetChanged(piece);
if (!sourceSheet.isNull())
{
emit layout->PieceTransformationChanged(piece);
}
emit layout->PieceSelectionChanged(piece);
}
}
@ -115,7 +132,7 @@ void VPUndoMovePieceOnSheet::redo()
piece->SetSelected(false);
}
if (m_followGrainline || piece->IsFollowGrainline())
if ((m_followGrainline || piece->IsFollowGrainline()) && !sourceSheet.isNull())
{
QT_WARNING_PUSH
QT_WARNING_DISABLE_GCC("-Wnoexcept")
@ -131,7 +148,10 @@ void VPUndoMovePieceOnSheet::redo()
if (not layout.isNull())
{
emit layout->PieceSheetChanged(piece);
emit layout->PieceTransformationChanged(piece);
if (!sourceSheet.isNull())
{
emit layout->PieceTransformationChanged(piece);
}
emit layout->LayoutChanged();
}
}

View File

@ -57,6 +57,7 @@
#include "../vmisc/dialogs/dialogselectlanguage.h"
#include "../vmisc/lambdaconstants.h"
#include "../vmisc/projectversion.h"
#include "../vmisc/theme/themeDef.h"
#include "../vmisc/theme/vtheme.h"
#include "../vmisc/vsysexits.h"
#include "../vwidgets/vmaingraphicsscene.h"
@ -728,13 +729,13 @@ void VPMainWindow::SetupMenu()
// Add Undo/Redo actions.
undoAction = m_layout->UndoStack()->createUndoAction(this, tr("&Undo"));
m_actionShortcuts.insert(VShortcutAction::Undo, undoAction);
undoAction->setIcon(QIcon::fromTheme(QStringLiteral("edit-undo")));
undoAction->setIcon(FromTheme(VThemeIcon::EditUndo));
ui->menuSheet->addAction(undoAction);
ui->toolBarUndoCommands->addAction(undoAction);
redoAction = m_layout->UndoStack()->createRedoAction(this, tr("&Redo"));
m_actionShortcuts.insert(VShortcutAction::Redo, redoAction);
redoAction->setIcon(QIcon::fromTheme(QStringLiteral("edit-redo")));
redoAction->setIcon(FromTheme(VThemeIcon::EditRedo));
ui->menuSheet->addAction(redoAction);
ui->toolBarUndoCommands->addAction(redoAction);
@ -883,6 +884,17 @@ void VPMainWindow::InitPropertyTabCurrentPiece()
connect(ui->checkBoxCurrentPieceHorizontallyFlipped, &QCheckBox::toggled, this,
&VPMainWindow::CurrentPieceHorizontallyFlippedToggled);
const QIcon warningIcon = FromTheme(VThemeIcon::DialogWarning);
auto WarningIcon = [warningIcon](QLabel *label)
{
const int size = qRound(16 * label->devicePixelRatio());
label->setPixmap(warningIcon.pixmap(size, size));
};
WarningIcon(ui->labelWarningOutOfBound);
WarningIcon(ui->labelWarningSuperpositionOfPieces);
WarningIcon(ui->labelWarningPieceGape);
// Translate
ui->comboBoxTranslateUnit->addItem(tr("Millimiters"), QVariant(UnitsToStr(Unit::Mm)));
ui->comboBoxTranslateUnit->addItem(tr("Centimeters"), QVariant(UnitsToStr(Unit::Cm)));
@ -1119,7 +1131,7 @@ void VPMainWindow::InitMarginsData(const QString &suffix)
LayoutWasSaved(false);
m_layout->TileFactory()->RefreshTileInfos();
m_graphicsView->RefreshLayout();
m_layout->CheckPiecesPositionValidity(sheet);
sheet->CheckPiecesPositionValidity();
}
}
});
@ -1356,12 +1368,14 @@ void VPMainWindow::SetPropertyTabCurrentPieceData()
ui->labelCurrentPieceNoPieceSelected->setVisible(true);
ui->groupBoxCurrentPieceInfo->setVisible(false);
ui->groupBoxCurrentPieceStatus->setVisible(false);
ui->groupBoxPieceTransformation->setVisible(false);
ui->groupBoxCurrentPieceGeometry->setVisible(false);
}
else if (selectedPieces.count() == 1)
{
ui->groupBoxCurrentPieceInfo->setVisible(true);
ui->groupBoxCurrentPieceStatus->setVisible(true);
ui->groupBoxPieceTransformation->setVisible(true);
ui->groupBoxCurrentPieceGeometry->setVisible(true);
@ -1373,6 +1387,10 @@ void VPMainWindow::SetPropertyTabCurrentPieceData()
SetLineEditValue(ui->lineEditCurrentPieceGradationId, selectedPiece->GetGradationId());
SetLineEditValue(ui->lineEditCopyNumber, QString::number(selectedPiece->CopyNumber()));
ui->labelWarningOutOfBound->setEnabled(selectedPiece->OutOfBound());
ui->labelWarningSuperpositionOfPieces->setEnabled(selectedPiece->HasSuperpositionWithPieces());
ui->labelWarningPieceGape->setEnabled(selectedPiece->HasInvalidPieceGapPosition());
SetCheckBoxValue(ui->checkBoxCurrentPieceShowSeamline, not selectedPiece->IsHideMainPath());
SetCheckBoxValue(ui->checkBoxCurrentPieceVerticallyFlipped, selectedPiece->IsVerticallyFlipped());
SetCheckBoxValue(ui->checkBoxCurrentPieceHorizontallyFlipped, selectedPiece->IsHorizontallyFlipped());
@ -1401,6 +1419,7 @@ void VPMainWindow::SetPropertyTabCurrentPieceData()
{
// show the content "multiple pieces selected"
ui->groupBoxCurrentPieceInfo->setVisible(false);
ui->groupBoxCurrentPieceStatus->setVisible(false);
ui->groupBoxPieceTransformation->setVisible(true);
ui->groupBoxCurrentPieceGeometry->setVisible(false);
@ -2140,7 +2159,10 @@ void VPMainWindow::SheetPaperSizeChanged()
}
else
{
m_layout->CheckPiecesPositionValidity(m_layout->GetFocusedSheet());
if (VPSheetPtr sheet = m_layout->GetFocusedSheet(); !sheet.isNull())
{
sheet->CheckPiecesPositionValidity();
}
}
}
@ -3908,7 +3930,7 @@ void VPMainWindow::on_SheetMarginChanged()
LayoutWasSaved(false);
m_layout->CheckPiecesPositionValidity(sheet);
sheet->CheckPiecesPositionValidity();
}
m_graphicsView->RefreshLayout();
@ -4910,7 +4932,10 @@ void VPMainWindow::LayoutWarningPieceGapePosition_toggled(bool checked)
LayoutWasSaved(false);
if (checked)
{
m_layout->CheckPiecesPositionValidity(m_layout->GetFocusedSheet());
if (VPSheetPtr sheet = m_layout->GetFocusedSheet(); !sheet.isNull())
{
sheet->CheckPiecesPositionValidity();
}
}
m_graphicsView->RefreshPieces();
}
@ -4925,7 +4950,11 @@ void VPMainWindow::LayoutWarningPiecesSuperposition_toggled(bool checked)
LayoutWasSaved(false);
if (checked)
{
m_layout->CheckPiecesPositionValidity(m_layout->GetFocusedSheet());
if (VPSheetPtr sheet = m_layout->GetFocusedSheet(); !sheet.isNull())
{
sheet->CheckPiecesPositionValidity();
}
}
m_graphicsView->RefreshPieces();
}
@ -4941,7 +4970,10 @@ void VPMainWindow::LayoutWarningPiecesOutOfBound_toggled(bool checked)
if (checked)
{
m_layout->CheckPiecesPositionValidity(m_layout->GetFocusedSheet());
if (VPSheetPtr sheet = m_layout->GetFocusedSheet(); !sheet.isNull())
{
sheet->CheckPiecesPositionValidity();
}
}
m_graphicsView->RefreshPieces();
}
@ -4954,7 +4986,10 @@ void VPMainWindow::LayoutCutOnFold_toggled(bool checked)
{
m_layout->LayoutSettings().SetCutOnFold(checked);
LayoutWasSaved(false);
m_layout->CheckPiecesPositionValidity(m_layout->GetFocusedSheet());
if (VPSheetPtr sheet = m_layout->GetFocusedSheet(); !sheet.isNull())
{
sheet->CheckPiecesPositionValidity();
}
m_graphicsView->RefreshLayout();
}
}

View File

@ -279,8 +279,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>378</width>
<height>752</height>
<width>385</width>
<height>865</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_23">
@ -395,6 +395,57 @@
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBoxCurrentPieceStatus">
<property name="title">
<string>Status</string>
</property>
<layout class="QFormLayout" name="formLayout">
<item row="0" column="0">
<widget class="QLabel" name="labelWarningOutOfBound">
<property name="text">
<string notr="true">Warning!</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="label_8">
<property name="text">
<string>Out of bound</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="labelWarningSuperpositionOfPieces">
<property name="text">
<string notr="true">Warning!</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLabel" name="label_10">
<property name="text">
<string>Superposition of pieces</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="labelWarningPieceGape">
<property name="text">
<string notr="true">Warning!</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLabel" name="label_16">
<property name="text">
<string>Piece gape</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBoxPieceTransformation">
<property name="sizePolicy">
@ -752,7 +803,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>378</width>
<width>385</width>
<height>829</height>
</rect>
</property>
@ -1276,7 +1327,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>392</width>
<width>399</width>
<height>700</height>
</rect>
</property>
@ -1659,7 +1710,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>378</width>
<width>385</width>
<height>710</height>
</rect>
</property>
@ -2455,8 +2506,8 @@
</resources>
<connections/>
<buttongroups>
<buttongroup name="buttonGroupRotationDirection"/>
<buttongroup name="buttonGroupTileOrientation"/>
<buttongroup name="buttonGroupSheetOrientation"/>
<buttongroup name="buttonGroupRotationDirection"/>
</buttongroups>
</ui>

View File

@ -38,6 +38,7 @@
#include "../vmisc/dialogs/dialogexporttocsv.h"
#include "../vmisc/dialogs/dialogselectlanguage.h"
#include "../vmisc/qxtcsvmodel.h"
#include "../vmisc/theme/themeDef.h"
#include "../vmisc/theme/vtheme.h"
#include "../vmisc/vsysexits.h"
#include "dialogs/dialogabouttape.h"
@ -1199,13 +1200,13 @@ void TKMMainWindow::DeployFormula()
{
ui->plainTextEditFormula->setFixedHeight(DIALOG_MAX_FORMULA_HEIGHT);
// Set icon from theme (internal for Windows system)
ui->pushButtonGrow->setIcon(QIcon::fromTheme(QStringLiteral("go-next")));
ui->pushButtonGrow->setIcon(FromTheme(VThemeIcon::GoNext));
}
else
{
ui->plainTextEditFormula->setFixedHeight(m_formulaBaseHeight);
// Set icon from theme (internal for Windows system)
ui->pushButtonGrow->setIcon(QIcon::fromTheme(QStringLiteral("go-down")));
ui->pushButtonGrow->setIcon(FromTheme(VThemeIcon::GoDown));
}
// I found that after change size of formula field, it was filed for angle formula, field for formula became black.

View File

@ -45,6 +45,7 @@
#include "../vmisc/dialogs/dialogselectlanguage.h"
#include "../vmisc/literals.h"
#include "../vmisc/qxtcsvmodel.h"
#include "../vmisc/theme/themeDef.h"
#include "../vmisc/theme/vtheme.h"
#include "../vmisc/vsysexits.h"
#include "../vpatterndb/calculator.h"
@ -2161,13 +2162,13 @@ void TMainWindow::DeployFormula()
{
ui->plainTextEditFormula->setFixedHeight(DIALOG_MAX_FORMULA_HEIGHT);
// Set icon from theme (internal for Windows system)
ui->pushButtonGrow->setIcon(QIcon::fromTheme(QStringLiteral("go-next")));
ui->pushButtonGrow->setIcon(FromTheme(VThemeIcon::GoNext));
}
else
{
ui->plainTextEditFormula->setFixedHeight(m_formulaBaseHeight);
// Set icon from theme (internal for Windows system)
ui->pushButtonGrow->setIcon(QIcon::fromTheme(QStringLiteral("go-down")));
ui->pushButtonGrow->setIcon(FromTheme(VThemeIcon::GoDown));
}
// I found that after change size of formula field, it was filed for angle formula, field for formula became black.

View File

@ -29,6 +29,7 @@
#include "dialogfinalmeasurements.h"
#include "../qmuparser/qmudef.h"
#include "../vmisc/compatibility.h"
#include "../vmisc/theme/themeDef.h"
#include "../vmisc/theme/vtheme.h"
#include "../vmisc/vabstractvalapplication.h"
#include "../vmisc/vvalentinasettings.h"
@ -441,13 +442,13 @@ void DialogFinalMeasurements::DeployFormula()
{
ui->plainTextEditFormula->setFixedHeight(DIALOG_MAX_FORMULA_HEIGHT);
// Set icon from theme (internal for Windows system)
ui->pushButtonGrow->setIcon(QIcon::fromTheme(QStringLiteral("go-next")));
ui->pushButtonGrow->setIcon(FromTheme(VThemeIcon::GoNext));
}
else
{
ui->plainTextEditFormula->setFixedHeight(formulaBaseHeight);
// Set icon from theme (internal for Windows system)
ui->pushButtonGrow->setIcon(QIcon::fromTheme(QStringLiteral("go-down")));
ui->pushButtonGrow->setIcon(FromTheme(VThemeIcon::GoDown));
}
// I found that after change size of formula field, it was filed for angle formula, field for formula became black.

View File

@ -1886,13 +1886,13 @@ void DialogIncrements::DeployFormula()
{
plainTextEditFormula->setFixedHeight(DIALOG_MAX_FORMULA_HEIGHT);
// Set icon from theme (internal for Windows system)
pushButtonGrow->setIcon(QIcon::fromTheme(QStringLiteral("go-next")));
pushButtonGrow->setIcon(FromTheme(VThemeIcon::GoNext));
}
else
{
plainTextEditFormula->setFixedHeight(baseHeight);
// Set icon from theme (internal for Windows system)
pushButtonGrow->setIcon(QIcon::fromTheme(QStringLiteral("go-down")));
pushButtonGrow->setIcon(FromTheme(VThemeIcon::GoDown));
}
// I found that after change size of formula field, it was filed for angle formula, field for formula became black.

View File

@ -30,6 +30,7 @@
#include "../ifc/xml/vbackgroundpatternimage.h"
#include "../vmisc/def.h"
#include "../vmisc/lambdaconstants.h"
#include "../vmisc/theme/themeDef.h"
#include "../vmisc/theme/vtheme.h"
#include "../vmisc/vabstractapplication.h"
#include "../vtools/undocommands/image/hideallbackgroundimages.h"
@ -355,7 +356,7 @@ void VWidgetBackgroundImages::ContextMenu(const QPoint &pos)
QAction *actionReset = menu.addAction(tr("Reset transformation"));
actionReset->setEnabled(not image.Hold());
QAction *actionDelete = menu.addAction(QIcon::fromTheme(editDeleteIcon), tr("Delete"));
QAction *actionDelete = menu.addAction(FromTheme(VThemeIcon::EditDelete), tr("Delete"));
menu.addSeparator();
QAction *actionHoldAll = menu.addAction(tr("Hold All"));

View File

@ -217,15 +217,13 @@ void VWidgetDetails::ToggledPieceItem(QTableWidgetItem *item)
const bool inLayout = details->value(id).IsInLayout();
if (inLayout)
{
item->setIcon(
QIcon::fromTheme(QStringLiteral("gtk-ok"),
VTheme::GetFallbackThemeIcon(QStringLiteral("16/actions/gtk-ok"), QSize(16, 16))));
item->setIcon(FromTheme(VThemeIcon::GtkOk,
VTheme::GetFallbackThemeIcon(QStringLiteral("16/actions/gtk-ok"), QSize(16, 16))));
}
else
{
item->setIcon(
QIcon::fromTheme(QStringLiteral("gtk-no"),
VTheme::GetFallbackThemeIcon(QStringLiteral("16/actions/gtk-no"), QSize(16, 16))));
item->setIcon(FromTheme(VThemeIcon::GtkNo,
VTheme::GetFallbackThemeIcon(QStringLiteral("16/actions/gtk-no"), QSize(16, 16))));
}
VToolSeamAllowance *tool = nullptr;
@ -249,15 +247,13 @@ auto VWidgetDetails::PrepareInLayoutColumnCell(const VPiece &det, quint32 id) ->
if (det.IsInLayout())
{
item->setIcon(
QIcon::fromTheme(QStringLiteral("gtk-ok"),
VTheme::GetFallbackThemeIcon(QStringLiteral("16/actions/gtk-ok"), QSize(16, 16))));
item->setIcon(FromTheme(VThemeIcon::GtkOk,
VTheme::GetFallbackThemeIcon(QStringLiteral("16/actions/gtk-ok"), QSize(16, 16))));
}
else
{
item->setIcon(
QIcon::fromTheme(QStringLiteral("gtk-no"),
VTheme::GetFallbackThemeIcon(QStringLiteral("16/actions/gtk-no"), QSize(16, 16))));
item->setIcon(FromTheme(VThemeIcon::GtkNo,
VTheme::GetFallbackThemeIcon(QStringLiteral("16/actions/gtk-no"), QSize(16, 16))));
}
item->setData(Qt::UserRole, id);
@ -312,16 +308,14 @@ void VWidgetDetails::ShowContextMenu(const QPoint &pos)
try
{
toolPiece = qobject_cast<VToolSeamAllowance *>(VAbstractPattern::getTool(id));
if (toolPiece)
if (toolPiece != nullptr)
{
pieceMode = true;
menu->addSeparator();
actionPieceOptions =
menu->addAction(QIcon::fromTheme(QStringLiteral("preferences-other")), tr("Piece options"));
actionPieceOptions = menu->addAction(FromTheme(VThemeIcon::PreferencesOther), tr("Piece options"));
actionDeletePiece =
menu->addAction(QIcon::fromTheme(QStringLiteral("edit-delete")), tr("Delete piece"));
actionDeletePiece = menu->addAction(FromTheme(VThemeIcon::EditDelete), tr("Delete piece"));
actionDeletePiece->setDisabled(toolPiece->referens() > 0);
}
}

View File

@ -293,8 +293,8 @@ void VWidgetGroups::CtxMenu(const QPoint &pos)
? menu->addAction(VTheme::GetIconResource(resource, QStringLiteral("16x16/closed_eye.png")), tr("Hide"))
: menu->addAction(VTheme::GetIconResource(resource, QStringLiteral("16x16/open_eye.png")), tr("Show"));
QAction *actionPreferences = menu->addAction(QIcon::fromTheme(preferencesOtherIcon), tr("Preferences"));
QAction *actionDelete = menu->addAction(QIcon::fromTheme(editDeleteIcon), tr("Delete"));
QAction *actionPreferences = menu->addAction(FromTheme(VThemeIcon::PreferencesOther), tr("Preferences"));
QAction *actionDelete = menu->addAction(FromTheme(VThemeIcon::EditDelete), tr("Delete"));
menu->addSeparator();
QAction *actionHideAll = menu->addAction(tr("Hide All"));
actionHideAll->setEnabled(MultipleChangeVisibilityTo(false));

View File

@ -5793,14 +5793,14 @@ void MainWindow::CreateMenus()
undoAction = VAbstractApplication::VApp()->getUndoStack()->createUndoAction(this, tr("&Undo"));
connect(undoAction, &QAction::triggered, m_toolOptions, &VToolOptionsPropertyBrowser::RefreshOptions);
m_shortcutActions.insert(VShortcutAction::Undo, undoAction);
undoAction->setIcon(QIcon::fromTheme(QStringLiteral("edit-undo")));
undoAction->setIcon(FromTheme(VThemeIcon::EditUndo));
ui->menuPatternPiece->insertAction(ui->actionLast_tool, undoAction);
ui->toolBarTools->addAction(undoAction);
redoAction = VAbstractApplication::VApp()->getUndoStack()->createRedoAction(this, tr("&Redo"));
connect(redoAction, &QAction::triggered, m_toolOptions, &VToolOptionsPropertyBrowser::RefreshOptions);
m_shortcutActions.insert(VShortcutAction::Redo, redoAction);
redoAction->setIcon(QIcon::fromTheme(QStringLiteral("edit-redo")));
redoAction->setIcon(FromTheme(VThemeIcon::EditRedo));
ui->menuPatternPiece->insertAction(ui->actionLast_tool, redoAction);
ui->toolBarTools->addAction(redoAction);

View File

@ -32,8 +32,6 @@
const QString LONG_OPTION_NO_HDPI_SCALING = QStringLiteral("no-scaling");
const QString editDeleteIcon = QStringLiteral("edit-delete");
const QString preferencesOtherIcon = QStringLiteral("preferences-other");
const QString degreeSymbol = QStringLiteral("°");
const QString trueStr = QStringLiteral("true");
const QString falseStr = QStringLiteral("false");

View File

@ -41,8 +41,6 @@ class QStringList;
extern const QString LONG_OPTION_NO_HDPI_SCALING;
extern const QString editDeleteIcon;
extern const QString preferencesOtherIcon;
extern const QString degreeSymbol;
extern const QString trueStr;
extern const QString falseStr;

View File

@ -0,0 +1,407 @@
/************************************************************************
**
** @file themeDef.cpp
** @author Roman Telezhynskyi <dismine(at)gmail.com>
** @date 22 4, 2024
**
** @brief
** @copyright
** This source code is part of the Valentina project, a pattern making
** program, whose allow create and modeling patterns of clothing.
** Copyright (C) 2024 Valentina project
** <https://gitlab.com/smart-pattern/valentina> 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 <http://www.gnu.org/licenses/>.
**
*************************************************************************/
#include "themeDef.h"
#include <QHash>
#include <QIcon>
#if QT_VERSION < QT_VERSION_CHECK(6, 4, 0)
#include "../compatibility.h"
#endif
using namespace Qt::Literals::StringLiterals;
namespace
{
QT_WARNING_PUSH
QT_WARNING_DISABLE_CLANG("-Wunused-member-function")
#if QT_VERSION >= QT_VERSION_CHECK(6, 7, 0)
using ThemeIconHash = QHash<VThemeIcon, QIcon::ThemeIcon>;
// NOLINTNEXTLINE
Q_GLOBAL_STATIC_WITH_ARGS(const ThemeIconHash, themeIconMapping,
({{VThemeIcon::AddressBookNew, QIcon::ThemeIcon::AddressBookNew},
{VThemeIcon::ApplicationExit, QIcon::ThemeIcon::ApplicationExit},
{VThemeIcon::AppointmentNew, QIcon::ThemeIcon::AppointmentNew},
{VThemeIcon::CallStart, QIcon::ThemeIcon::CallStart},
{VThemeIcon::CallStop, QIcon::ThemeIcon::CallStop},
{VThemeIcon::ContactNew, QIcon::ThemeIcon::ContactNew},
{VThemeIcon::DocumentNew, QIcon::ThemeIcon::DocumentNew},
{VThemeIcon::DocumentOpen, QIcon::ThemeIcon::DocumentOpen},
{VThemeIcon::DocumentOpenRecent, QIcon::ThemeIcon::DocumentOpenRecent},
{VThemeIcon::DocumentPageSetup, QIcon::ThemeIcon::DocumentPageSetup},
{VThemeIcon::DocumentPrint, QIcon::ThemeIcon::DocumentPrint},
{VThemeIcon::DocumentPrintPreview, QIcon::ThemeIcon::DocumentPrintPreview},
{VThemeIcon::DocumentProperties, QIcon::ThemeIcon::DocumentProperties},
{VThemeIcon::DocumentRevert, QIcon::ThemeIcon::DocumentRevert},
{VThemeIcon::DocumentSave, QIcon::ThemeIcon::DocumentSave},
{VThemeIcon::DocumentSaveAs, QIcon::ThemeIcon::DocumentSaveAs},
{VThemeIcon::DocumentSend, QIcon::ThemeIcon::DocumentSend},
{VThemeIcon::EditClear, QIcon::ThemeIcon::EditClear},
{VThemeIcon::EditCopy, QIcon::ThemeIcon::EditCopy},
{VThemeIcon::EditCut, QIcon::ThemeIcon::EditCut},
{VThemeIcon::EditDelete, QIcon::ThemeIcon::EditDelete},
{VThemeIcon::EditFind, QIcon::ThemeIcon::EditFind},
{VThemeIcon::EditPaste, QIcon::ThemeIcon::EditPaste},
{VThemeIcon::EditRedo, QIcon::ThemeIcon::EditRedo},
{VThemeIcon::EditSelectAll, QIcon::ThemeIcon::EditSelectAll},
{VThemeIcon::EditUndo, QIcon::ThemeIcon::EditUndo},
{VThemeIcon::FolderNew, QIcon::ThemeIcon::FolderNew},
{VThemeIcon::FormatIndentLess, QIcon::ThemeIcon::FormatIndentLess},
{VThemeIcon::FormatIndentMore, QIcon::ThemeIcon::FormatIndentMore},
{VThemeIcon::FormatJustifyCenter, QIcon::ThemeIcon::FormatJustifyCenter},
{VThemeIcon::FormatJustifyFill, QIcon::ThemeIcon::FormatJustifyFill},
{VThemeIcon::FormatJustifyLeft, QIcon::ThemeIcon::FormatJustifyLeft},
{VThemeIcon::FormatJustifyRight, QIcon::ThemeIcon::FormatJustifyRight},
{VThemeIcon::FormatTextDirectionLtr, QIcon::ThemeIcon::FormatTextDirectionLtr},
{VThemeIcon::FormatTextDirectionRtl, QIcon::ThemeIcon::FormatTextDirectionRtl},
{VThemeIcon::FormatTextBold, QIcon::ThemeIcon::FormatTextBold},
{VThemeIcon::FormatTextItalic, QIcon::ThemeIcon::FormatTextItalic},
{VThemeIcon::FormatTextUnderline, QIcon::ThemeIcon::FormatTextUnderline},
{VThemeIcon::FormatTextStrikethrough, QIcon::ThemeIcon::FormatTextStrikethrough},
{VThemeIcon::GoDown, QIcon::ThemeIcon::GoDown},
{VThemeIcon::GoHome, QIcon::ThemeIcon::GoHome},
{VThemeIcon::GoNext, QIcon::ThemeIcon::GoNext},
{VThemeIcon::GoPrevious, QIcon::ThemeIcon::GoPrevious},
{VThemeIcon::GoUp, QIcon::ThemeIcon::GoUp},
{VThemeIcon::HelpAbout, QIcon::ThemeIcon::HelpAbout},
{VThemeIcon::HelpFaq, QIcon::ThemeIcon::HelpFaq},
{VThemeIcon::InsertImage, QIcon::ThemeIcon::InsertImage},
{VThemeIcon::InsertLink, QIcon::ThemeIcon::InsertLink},
{VThemeIcon::InsertText, QIcon::ThemeIcon::InsertText},
{VThemeIcon::ListAdd, QIcon::ThemeIcon::InsertText},
{VThemeIcon::ListRemove, QIcon::ThemeIcon::ListRemove},
{VThemeIcon::MailForward, QIcon::ThemeIcon::MailForward},
{VThemeIcon::MailMarkImportant, QIcon::ThemeIcon::MailMarkImportant},
{VThemeIcon::MailMarkRead, QIcon::ThemeIcon::MailMarkRead},
{VThemeIcon::MailMarkUnread, QIcon::ThemeIcon::MailMarkUnread},
{VThemeIcon::MailMessageNew, QIcon::ThemeIcon::MailMessageNew},
{VThemeIcon::MailReplyAll, QIcon::ThemeIcon::MailReplyAll},
{VThemeIcon::MailReplySender, QIcon::ThemeIcon::MailReplySender},
{VThemeIcon::MailSend, QIcon::ThemeIcon::MailSend},
{VThemeIcon::MediaEject, QIcon::ThemeIcon::MediaEject},
{VThemeIcon::MediaPlaybackPause, QIcon::ThemeIcon::MediaPlaybackPause},
{VThemeIcon::MediaPlaybackStart, QIcon::ThemeIcon::MediaPlaybackStart},
{VThemeIcon::MediaPlaybackStop, QIcon::ThemeIcon::MediaPlaybackStop},
{VThemeIcon::MediaRecord, QIcon::ThemeIcon::MediaRecord},
{VThemeIcon::MediaSeekBackward, QIcon::ThemeIcon::MediaSeekBackward},
{VThemeIcon::MediaSeekForward, QIcon::ThemeIcon::MediaSeekForward},
{VThemeIcon::MediaSkipBackward, QIcon::ThemeIcon::MediaSkipBackward},
{VThemeIcon::MediaSkipForward, QIcon::ThemeIcon::MediaSkipForward},
{VThemeIcon::ObjectRotateLeft, QIcon::ThemeIcon::ObjectRotateLeft},
{VThemeIcon::ObjectRotateRight, QIcon::ThemeIcon::ObjectRotateRight},
{VThemeIcon::ProcessStop, QIcon::ThemeIcon::ProcessStop},
{VThemeIcon::SystemLockScreen, QIcon::ThemeIcon::SystemLockScreen},
{VThemeIcon::SystemLogOut, QIcon::ThemeIcon::SystemLogOut},
{VThemeIcon::SystemSearch, QIcon::ThemeIcon::SystemSearch},
{VThemeIcon::SystemReboot, QIcon::ThemeIcon::SystemReboot},
{VThemeIcon::SystemShutdown, QIcon::ThemeIcon::SystemShutdown},
{VThemeIcon::ToolsCheckSpelling, QIcon::ThemeIcon::ToolsCheckSpelling},
{VThemeIcon::ViewFullscreen, QIcon::ThemeIcon::ViewFullscreen},
{VThemeIcon::ViewRefresh, QIcon::ThemeIcon::ViewRefresh},
{VThemeIcon::ViewRestore, QIcon::ThemeIcon::ViewRestore},
{VThemeIcon::WindowClose, QIcon::ThemeIcon::WindowClose},
{VThemeIcon::WindowNew, QIcon::ThemeIcon::WindowNew},
{VThemeIcon::ZoomFitBest, QIcon::ThemeIcon::ZoomFitBest},
{VThemeIcon::ZoomIn, QIcon::ThemeIcon::ZoomIn},
{VThemeIcon::ZoomOut, QIcon::ThemeIcon::ZoomOut},
{VThemeIcon::AudioCard, QIcon::ThemeIcon::AudioCard},
{VThemeIcon::AudioInputMicrophone, QIcon::ThemeIcon::AudioInputMicrophone},
{VThemeIcon::Battery, QIcon::ThemeIcon::Battery},
{VThemeIcon::CameraPhoto, QIcon::ThemeIcon::CameraPhoto},
{VThemeIcon::CameraVideo, QIcon::ThemeIcon::CameraVideo},
{VThemeIcon::CameraWeb, QIcon::ThemeIcon::CameraWeb},
{VThemeIcon::Computer, QIcon::ThemeIcon::Computer},
{VThemeIcon::DriveHarddisk, QIcon::ThemeIcon::DriveHarddisk},
{VThemeIcon::DriveOptical, QIcon::ThemeIcon::DriveOptical},
{VThemeIcon::InputGaming, QIcon::ThemeIcon::InputGaming},
{VThemeIcon::InputKeyboard, QIcon::ThemeIcon::InputKeyboard},
{VThemeIcon::InputMouse, QIcon::ThemeIcon::InputMouse},
{VThemeIcon::InputTablet, QIcon::ThemeIcon::InputTablet},
{VThemeIcon::MediaFlash, QIcon::ThemeIcon::MediaFlash},
{VThemeIcon::MediaOptical, QIcon::ThemeIcon::MediaOptical},
{VThemeIcon::MediaTape, QIcon::ThemeIcon::MediaTape},
{VThemeIcon::MultimediaPlayer, QIcon::ThemeIcon::MultimediaPlayer},
{VThemeIcon::NetworkWired, QIcon::ThemeIcon::NetworkWired},
{VThemeIcon::NetworkWireless, QIcon::ThemeIcon::NetworkWireless},
{VThemeIcon::Phone, QIcon::ThemeIcon::Phone},
{VThemeIcon::Printer, QIcon::ThemeIcon::Printer},
{VThemeIcon::Scanner, QIcon::ThemeIcon::Scanner},
{VThemeIcon::VideoDisplay, QIcon::ThemeIcon::VideoDisplay},
{VThemeIcon::AppointmentMissed, QIcon::ThemeIcon::AppointmentMissed},
{VThemeIcon::AppointmentSoon, QIcon::ThemeIcon::AppointmentSoon},
{VThemeIcon::AudioVolumeHigh, QIcon::ThemeIcon::AudioVolumeHigh},
{VThemeIcon::AudioVolumeLow, QIcon::ThemeIcon::AudioVolumeLow},
{VThemeIcon::AudioVolumeMedium, QIcon::ThemeIcon::AudioVolumeMedium},
{VThemeIcon::AudioVolumeMuted, QIcon::ThemeIcon::AudioVolumeMuted},
{VThemeIcon::BatteryCaution, QIcon::ThemeIcon::BatteryCaution},
{VThemeIcon::BatteryLow, QIcon::ThemeIcon::BatteryLow},
{VThemeIcon::DialogError, QIcon::ThemeIcon::DialogError},
{VThemeIcon::DialogInformation, QIcon::ThemeIcon::DialogInformation},
{VThemeIcon::DialogPassword, QIcon::ThemeIcon::DialogPassword},
{VThemeIcon::DialogQuestion, QIcon::ThemeIcon::DialogQuestion},
{VThemeIcon::DialogWarning, QIcon::ThemeIcon::DialogWarning},
{VThemeIcon::FolderDragAccept, QIcon::ThemeIcon::FolderDragAccept},
{VThemeIcon::FolderOpen, QIcon::ThemeIcon::FolderOpen},
{VThemeIcon::FolderVisiting, QIcon::ThemeIcon::FolderVisiting},
{VThemeIcon::ImageLoading, QIcon::ThemeIcon::ImageLoading},
{VThemeIcon::ImageMissing, QIcon::ThemeIcon::ImageMissing},
{VThemeIcon::MailAttachment, QIcon::ThemeIcon::MailAttachment},
{VThemeIcon::MailUnread, QIcon::ThemeIcon::MailUnread},
{VThemeIcon::MailRead, QIcon::ThemeIcon::MailRead},
{VThemeIcon::MailReplied, QIcon::ThemeIcon::MailReplied},
{VThemeIcon::MediaPlaylistRepeat, QIcon::ThemeIcon::MediaPlaylistRepeat},
{VThemeIcon::MediaPlaylistShuffle, QIcon::ThemeIcon::MediaPlaylistShuffle},
{VThemeIcon::NetworkOffline, QIcon::ThemeIcon::NetworkOffline},
{VThemeIcon::PrinterPrinting, QIcon::ThemeIcon::PrinterPrinting},
{VThemeIcon::SecurityHigh, QIcon::ThemeIcon::SecurityHigh},
{VThemeIcon::SecurityLow, QIcon::ThemeIcon::SecurityLow},
{VThemeIcon::SoftwareUpdateAvailable, QIcon::ThemeIcon::SoftwareUpdateAvailable},
{VThemeIcon::SoftwareUpdateUrgent, QIcon::ThemeIcon::SoftwareUpdateUrgent},
{VThemeIcon::SyncError, QIcon::ThemeIcon::SyncError},
{VThemeIcon::SyncSynchronizing, QIcon::ThemeIcon::SyncSynchronizing},
{VThemeIcon::UserAvailable, QIcon::ThemeIcon::UserAvailable},
{VThemeIcon::UserOffline, QIcon::ThemeIcon::UserOffline},
{VThemeIcon::WeatherClear, QIcon::ThemeIcon::WeatherClear},
{VThemeIcon::WeatherClearNight, QIcon::ThemeIcon::WeatherClearNight},
{VThemeIcon::WeatherFewClouds, QIcon::ThemeIcon::WeatherFewClouds},
{VThemeIcon::WeatherFewCloudsNight, QIcon::ThemeIcon::WeatherFewCloudsNight},
{VThemeIcon::WeatherFog, QIcon::ThemeIcon::WeatherFog},
{VThemeIcon::WeatherShowers, QIcon::ThemeIcon::WeatherShowers},
{VThemeIcon::WeatherSnow, QIcon::ThemeIcon::WeatherSnow},
{VThemeIcon::WeatherStorm, QIcon::ThemeIcon::WeatherStorm}}))
#endif
using ThemeIconStringHash = QHash<VThemeIcon, QString>;
// NOLINTNEXTLINE
Q_GLOBAL_STATIC_WITH_ARGS(const ThemeIconStringHash, themeIconStringMapping,
({{VThemeIcon::AddressBookNew, "address-book-new"_L1},
{VThemeIcon::ApplicationExit, "application-exit"_L1},
{VThemeIcon::AppointmentNew, "appointment-new"_L1},
{VThemeIcon::CallStart, "call-start"_L1},
{VThemeIcon::CallStop, "call-stop"_L1},
{VThemeIcon::ContactNew, "contact-new"_L1},
{VThemeIcon::DocumentNew, "document-new"_L1},
{VThemeIcon::DocumentOpen, "document-open"_L1},
{VThemeIcon::DocumentOpenRecent, "document-open-recent"_L1},
{VThemeIcon::DocumentPageSetup, "document-page-setup"_L1},
{VThemeIcon::DocumentPrint, "document-print"_L1},
{VThemeIcon::DocumentPrintPreview, "document-print-preview"_L1},
{VThemeIcon::DocumentProperties, "document-properties"_L1},
{VThemeIcon::DocumentRevert, "document-revert"_L1},
{VThemeIcon::DocumentSave, "document-save"_L1},
{VThemeIcon::DocumentSaveAs, "document-save-as"_L1},
{VThemeIcon::DocumentSend, "document-send"_L1},
{VThemeIcon::EditClear, "edit-clear"_L1},
{VThemeIcon::EditCopy, "edit-copy"_L1},
{VThemeIcon::EditCut, "edit-cut"_L1},
{VThemeIcon::EditDelete, "edit-delete"_L1},
{VThemeIcon::EditFind, "edit-find"_L1},
{VThemeIcon::EditPaste, "edit-paste"_L1},
{VThemeIcon::EditRedo, "edit-redo"_L1},
{VThemeIcon::EditSelectAll, "edit-select-all"_L1},
{VThemeIcon::EditUndo, "edit-undo"_L1},
{VThemeIcon::FolderNew, "folder-new"_L1},
{VThemeIcon::FormatIndentLess, "format-indent-less"_L1},
{VThemeIcon::FormatIndentMore, "format-indent-more"_L1},
{VThemeIcon::FormatJustifyCenter, "format-justify-center"_L1},
{VThemeIcon::FormatJustifyFill, "format-justify-fill"_L1},
{VThemeIcon::FormatJustifyLeft, "format-justify-left"_L1},
{VThemeIcon::FormatJustifyRight, "format-justify-right"_L1},
{VThemeIcon::FormatTextDirectionLtr, "format-text-direction-ltr"_L1},
{VThemeIcon::FormatTextDirectionRtl, "format-text-direction-rtl"_L1},
{VThemeIcon::FormatTextBold, "format-text-bold"_L1},
{VThemeIcon::FormatTextItalic, "format-text-italic"_L1},
{VThemeIcon::FormatTextUnderline, "format-text-underline"_L1},
{VThemeIcon::FormatTextStrikethrough, "format-text-strikethrough"_L1},
{VThemeIcon::GoDown, "go-down"_L1},
{VThemeIcon::GoHome, "go-home"_L1},
{VThemeIcon::GoNext, "go-next"_L1},
{VThemeIcon::GoPrevious, "go-previous"_L1},
{VThemeIcon::GoUp, "go-up"_L1},
{VThemeIcon::HelpAbout, "help-about"_L1},
{VThemeIcon::HelpFaq, "help-faq"_L1},
{VThemeIcon::InsertImage, "insert-image"_L1},
{VThemeIcon::InsertLink, "insert-link"_L1},
{VThemeIcon::InsertText, "insert-text"_L1},
{VThemeIcon::ListAdd, "list-add"_L1},
{VThemeIcon::ListRemove, "list-remove"_L1},
{VThemeIcon::MailForward, "mail-forward"_L1},
{VThemeIcon::MailMarkImportant, "mail-mark-important"_L1},
{VThemeIcon::MailMarkRead, "mail-mark-read"_L1},
{VThemeIcon::MailMarkUnread, "mail-mark-unread"_L1},
{VThemeIcon::MailMessageNew, "mail-message-new"_L1},
{VThemeIcon::MailReplyAll, "mail-reply-all"_L1},
{VThemeIcon::MailReplySender, "mail-reply-sender"_L1},
{VThemeIcon::MailSend, "mail-send"_L1},
{VThemeIcon::MediaEject, "media-eject"_L1},
{VThemeIcon::MediaPlaybackPause, "media-playback-pause"_L1},
{VThemeIcon::MediaPlaybackStart, "media-playback-start"_L1},
{VThemeIcon::MediaPlaybackStop, "media-playback-stop"_L1},
{VThemeIcon::MediaRecord, "media-record"_L1},
{VThemeIcon::MediaSeekBackward, "media-seek-backward"_L1},
{VThemeIcon::MediaSeekForward, "media-seek-forward"_L1},
{VThemeIcon::MediaSkipBackward, "media-skip-backward"_L1},
{VThemeIcon::MediaSkipForward, "media-skip-forward"_L1},
{VThemeIcon::ObjectRotateLeft, "object-rotate-left"_L1},
{VThemeIcon::ObjectRotateRight, "object-rotate-right"_L1},
{VThemeIcon::ProcessStop, "process-stop"_L1},
{VThemeIcon::SystemLockScreen, "system-lock-screen"_L1},
{VThemeIcon::SystemLogOut, "system-log-out"_L1},
{VThemeIcon::SystemSearch, "system-search"_L1},
{VThemeIcon::SystemReboot, "system-reboot"_L1},
{VThemeIcon::SystemShutdown, "system-shutdown"_L1},
{VThemeIcon::ToolsCheckSpelling, "tools-check-spelling"_L1},
{VThemeIcon::ViewFullscreen, "view-fullscreen"_L1},
{VThemeIcon::ViewRefresh, "view-refresh"_L1},
{VThemeIcon::ViewRestore, "view-restore"_L1},
{VThemeIcon::WindowClose, "window-close"_L1},
{VThemeIcon::WindowNew, "window-new"_L1},
{VThemeIcon::ZoomFitBest, "zoom-fit-best"_L1},
{VThemeIcon::ZoomIn, "zoom-in"_L1},
{VThemeIcon::ZoomOut, "zoom-out"_L1},
{VThemeIcon::AudioCard, "audio-card"_L1},
{VThemeIcon::AudioInputMicrophone, "audio-input-microphone"_L1},
{VThemeIcon::Battery, "battery"_L1},
{VThemeIcon::CameraPhoto, "camera-photo"_L1},
{VThemeIcon::CameraVideo, "camera-video"_L1},
{VThemeIcon::CameraWeb, "camera-web"_L1},
{VThemeIcon::Computer, "computer"_L1},
{VThemeIcon::DriveHarddisk, "drive-harddisk"},
{VThemeIcon::DriveOptical, "drive-optical"_L1},
{VThemeIcon::InputGaming, "input-gaming"_L1},
{VThemeIcon::InputKeyboard, "input-keyboard"_L1},
{VThemeIcon::InputMouse, "input-mouse"_L1},
{VThemeIcon::InputTablet, "input-tablet"_L1},
{VThemeIcon::MediaFlash, "media-flash"_L1},
{VThemeIcon::MediaOptical, "media-optical"_L1},
{VThemeIcon::MediaTape, "media-tape"_L1},
{VThemeIcon::MultimediaPlayer, "multimedia-player"_L1},
{VThemeIcon::NetworkWired, "network-wired"_L1},
{VThemeIcon::NetworkWireless, "network-wireless"_L1},
{VThemeIcon::Phone, "phone"_L1},
{VThemeIcon::Printer, "printer"_L1},
{VThemeIcon::Scanner, "scanner"_L1},
{VThemeIcon::VideoDisplay, "video-display"_L1},
{VThemeIcon::AppointmentMissed, "appointment-missed"_L1},
{VThemeIcon::AppointmentSoon, "appointment-soon"_L1},
{VThemeIcon::AudioVolumeHigh, "audio-volume-high"_L1},
{VThemeIcon::AudioVolumeLow, "audio-volume-low"_L1},
{VThemeIcon::AudioVolumeMedium, "audio-volume-medium"_L1},
{VThemeIcon::AudioVolumeMuted, "audio-volume-muted"_L1},
{VThemeIcon::BatteryCaution, "battery-caution"_L1},
{VThemeIcon::BatteryLow, "battery-low"_L1},
{VThemeIcon::DialogError, "dialog-error"_L1},
{VThemeIcon::DialogInformation, "dialog-information"_L1},
{VThemeIcon::DialogPassword, "dialog-password"_L1},
{VThemeIcon::DialogQuestion, "dialog-question"_L1},
{VThemeIcon::DialogWarning, "dialog-warning"_L1},
{VThemeIcon::FolderDragAccept, "folder-drag-accept"_L1},
{VThemeIcon::FolderOpen, "folder-open"_L1},
{VThemeIcon::FolderVisiting, "folder-visiting"_L1},
{VThemeIcon::ImageLoading, "image-loading"_L1},
{VThemeIcon::ImageMissing, "image-missing"_L1},
{VThemeIcon::MailAttachment, "mail-attachment"_L1},
{VThemeIcon::MailUnread, "mail-unread"_L1},
{VThemeIcon::MailRead, "mail-read"_L1},
{VThemeIcon::MailReplied, "mail-replied"_L1},
{VThemeIcon::MediaPlaylistRepeat, "media-playlist-repeat"_L1},
{VThemeIcon::MediaPlaylistShuffle, "media-playlist-shuffle"_L1},
{VThemeIcon::NetworkOffline, "network-offline"_L1},
{VThemeIcon::PrinterPrinting, "printer-printing"_L1},
{VThemeIcon::SecurityHigh, "security-high"_L1},
{VThemeIcon::SecurityLow, "security-low"_L1},
{VThemeIcon::SoftwareUpdateAvailable, "software-update-available"_L1},
{VThemeIcon::SoftwareUpdateUrgent, "software-update-urgent"_L1},
{VThemeIcon::SyncError, "sync-error"_L1},
{VThemeIcon::SyncSynchronizing, "sync-synchronizing"_L1},
{VThemeIcon::UserAvailable, "user-available"_L1},
{VThemeIcon::UserOffline, "user-offline"_L1},
{VThemeIcon::WeatherClear, "weather-clear"_L1},
{VThemeIcon::WeatherClearNight, "weather-clear-night"_L1},
{VThemeIcon::WeatherFewClouds, "weather-few-clouds"_L1},
{VThemeIcon::WeatherFewCloudsNight, "weather-few-clouds-night"_L1},
{VThemeIcon::WeatherFog, "weather-fog"_L1},
{VThemeIcon::WeatherShowers, "weather-showers"_L1},
{VThemeIcon::WeatherSnow, "weather-snow"_L1},
{VThemeIcon::WeatherStorm, "weather-storm"_L1},
{VThemeIcon::PreferencesOther, "preferences-other"_L1},
{VThemeIcon::GtkOk, "gtk-ok"_L1},
{VThemeIcon::GtkNo, "gtk-no"_L1}}))
QT_WARNING_POP
} // namespace
//---------------------------------------------------------------------------------------------------------------------
auto FromTheme(VThemeIcon icon) -> QIcon
{
#if QT_VERSION >= QT_VERSION_CHECK(6, 7, 0)
if (themeIconMapping->contains(icon))
{
return QIcon::fromTheme(themeIconMapping->value(icon));
}
return QIcon::fromTheme(themeIconStringMapping->value(icon));
#else
return QIcon::fromTheme(themeIconStringMapping->value(icon));
#endif
}
//---------------------------------------------------------------------------------------------------------------------
auto FromTheme(VThemeIcon icon, const QIcon &fallback) -> QIcon
{
#if QT_VERSION >= QT_VERSION_CHECK(6, 7, 0)
if (themeIconMapping->contains(icon))
{
return QIcon::fromTheme(themeIconMapping->value(icon), fallback);
}
return QIcon::fromTheme(themeIconStringMapping->value(icon), fallback);
#else
return QIcon::fromTheme(themeIconStringMapping->value(icon), fallback);
#endif
}
//---------------------------------------------------------------------------------------------------------------------
auto HasThemeIcon(VThemeIcon icon) -> bool
{
#if QT_VERSION >= QT_VERSION_CHECK(6, 7, 0)
if (themeIconMapping->contains(icon))
{
return QIcon::hasThemeIcon(themeIconMapping->value(icon));
}
return QIcon::hasThemeIcon(themeIconStringMapping->value(icon));
#else
return QIcon::hasThemeIcon(themeIconStringMapping->value(icon));
#endif
}

View File

@ -34,6 +34,8 @@
#include <QtCore/QHashFunctions>
#endif
class QIcon;
enum class VColorRole
{
DefaultColor,
@ -67,4 +69,178 @@ Q_DECL_CONST_FUNCTION inline auto qHash(VColorRole key, uint seed = 0) noexcept
}
#endif
enum class VThemeIcon
{
AddressBookNew,
ApplicationExit,
AppointmentNew,
CallStart,
CallStop,
ContactNew,
DocumentNew,
DocumentOpen,
DocumentOpenRecent,
DocumentPageSetup,
DocumentPrint,
DocumentPrintPreview,
DocumentProperties,
DocumentRevert,
DocumentSave,
DocumentSaveAs,
DocumentSend,
EditClear,
EditCopy,
EditCut,
EditDelete,
EditFind,
EditPaste,
EditRedo,
EditSelectAll,
EditUndo,
FolderNew,
FormatIndentLess,
FormatIndentMore,
FormatJustifyCenter,
FormatJustifyFill,
FormatJustifyLeft,
FormatJustifyRight,
FormatTextDirectionLtr,
FormatTextDirectionRtl,
FormatTextBold,
FormatTextItalic,
FormatTextUnderline,
FormatTextStrikethrough,
GoDown,
GoHome,
GoNext,
GoPrevious,
GoUp,
HelpAbout,
HelpFaq,
InsertImage,
InsertLink,
InsertText,
ListAdd,
ListRemove,
MailForward,
MailMarkImportant,
MailMarkRead,
MailMarkUnread,
MailMessageNew,
MailReplyAll,
MailReplySender,
MailSend,
MediaEject,
MediaPlaybackPause,
MediaPlaybackStart,
MediaPlaybackStop,
MediaRecord,
MediaSeekBackward,
MediaSeekForward,
MediaSkipBackward,
MediaSkipForward,
ObjectRotateLeft,
ObjectRotateRight,
ProcessStop,
SystemLockScreen,
SystemLogOut,
SystemSearch,
SystemReboot,
SystemShutdown,
ToolsCheckSpelling,
ViewFullscreen,
ViewRefresh,
ViewRestore,
WindowClose,
WindowNew,
ZoomFitBest,
ZoomIn,
ZoomOut,
AudioCard,
AudioInputMicrophone,
Battery,
CameraPhoto,
CameraVideo,
CameraWeb,
Computer,
DriveHarddisk,
DriveOptical,
InputGaming,
InputKeyboard,
InputMouse,
InputTablet,
MediaFlash,
MediaOptical,
MediaTape,
MultimediaPlayer,
NetworkWired,
NetworkWireless,
Phone,
Printer,
Scanner,
VideoDisplay,
AppointmentMissed,
AppointmentSoon,
AudioVolumeHigh,
AudioVolumeLow,
AudioVolumeMedium,
AudioVolumeMuted,
BatteryCaution,
BatteryLow,
DialogError,
DialogInformation,
DialogPassword,
DialogQuestion,
DialogWarning,
FolderDragAccept,
FolderOpen,
FolderVisiting,
ImageLoading,
ImageMissing,
MailAttachment,
MailUnread,
MailRead,
MailReplied,
MediaPlaylistRepeat,
MediaPlaylistShuffle,
NetworkOffline,
PrinterPrinting,
SecurityHigh,
SecurityLow,
SoftwareUpdateAvailable,
SoftwareUpdateUrgent,
SyncError,
SyncSynchronizing,
UserAvailable,
UserOffline,
WeatherClear,
WeatherClearNight,
WeatherFewClouds,
WeatherFewCloudsNight,
WeatherFog,
WeatherShowers,
WeatherSnow,
WeatherStorm,
// Not supported by Qt
PreferencesOther,
GtkOk,
GtkNo
};
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
Q_DECL_CONST_FUNCTION inline auto qHash(VThemeIcon key, uint seed = 0) noexcept -> uint
{
auto underlyingValue = static_cast<typename std::underlying_type<VThemeIcon>::type>(key);
return ::qHash(underlyingValue, seed);
}
#endif
auto FromTheme(VThemeIcon icon) -> QIcon;
auto FromTheme(VThemeIcon icon, const QIcon &fallback) -> QIcon;
auto HasThemeIcon(VThemeIcon icon) -> bool;
#endif // THEMEDEF_H

View File

@ -334,8 +334,7 @@ void VTheme::InitApplicationStyle()
//---------------------------------------------------------------------------------------------------------------------
void VTheme::SetIconTheme()
{
static const char *GENERIC_ICON_TO_CHECK = "document-open";
if (not QIcon::hasThemeIcon(GENERIC_ICON_TO_CHECK))
if (not HasThemeIcon(VThemeIcon::DocumentOpen))
{
// If there is no default working icon theme then we should
// use an icon theme that we provide via a .qrc file

View File

@ -149,9 +149,11 @@ template <typename Guarded> auto VLockGuard<Guarded>::TryLock(const QString &loc
bool res = true;
lockFile = lockName + QLatin1String(".lock");
#if defined(Q_OS_UNIX)
QFileInfo info(lockFile);
lockFile = info.absolutePath() + QLatin1String("/.") + info.fileName();
#if defined(Q_OS_UNIX) || defined(Q_OS_MACOS)
{
QFileInfo info(lockFile);
lockFile = info.absolutePath() + QLatin1String("/.") + info.fileName();
}
#endif
lock.reset(new QLockFile(lockFile));

View File

@ -142,6 +142,7 @@ VLib {
name: "theme"
prefix: "theme/"
files: [
"themeDef.cpp",
"themeDef.h",
"vapplicationstyle.cpp",
"vapplicationstyle.h",

View File

@ -37,6 +37,7 @@
#include "../vgeometry/vspline.h"
#include "../vgeometry/vsplinepath.h"
#include "../vmisc/def.h"
#include "../vmisc/theme/themeDef.h"
#include "../vmisc/vabstractapplication.h"
#include "../vpatterndb/calculator.h"
#include "../vpatterndb/variables/vcurvelength.h"
@ -223,13 +224,13 @@ void DeployFormula(QDialog *dialog, QPlainTextEdit *formula, QPushButton *button
{
formula->setFixedHeight(dialogMaxFormulaHeight);
// Set icon from theme (internal for Windows system)
buttonGrowLength->setIcon(QIcon::fromTheme(QStringLiteral("go-next")));
buttonGrowLength->setIcon(FromTheme(VThemeIcon::GoNext));
}
else
{
formula->setFixedHeight(formulaBaseHeight);
// Set icon from theme (internal for Windows system)
buttonGrowLength->setIcon(QIcon::fromTheme(QStringLiteral("go-down")));
buttonGrowLength->setIcon(FromTheme(VThemeIcon::GoDown));
}
// I found that after change size of formula field, it was filed for angle formula, field for formula became black.
@ -609,13 +610,13 @@ auto EachPointLabelIsUnique(QListWidget *listWidget) -> bool
//---------------------------------------------------------------------------------------------------------------------
auto DialogWarningIcon() -> QString
{
const QIcon icon = QIcon::fromTheme(QStringLiteral("dialog-warning"));
const QIcon icon = FromTheme(VThemeIcon::DialogWarning);
const QPixmap pixmap = icon.pixmap(QSize(16, 16));
QByteArray byteArray;
QBuffer buffer(&byteArray);
pixmap.save(&buffer, "PNG");
return QStringLiteral("<img src=\"data:image/png;base64,") + byteArray.toBase64() + QStringLiteral("\"/> ");
return QStringLiteral("<img src=\"data:image/png;base64,") + byteArray.toBase64() + "\"/> "_L1;
}
//---------------------------------------------------------------------------------------------------------------------

View File

@ -27,6 +27,7 @@
*************************************************************************/
#include "dialoginsertnode.h"
#include "../vmisc/theme/themeDef.h"
#include "../vpatterndb/vcontainer.h"
#include "ui_dialoginsertnode.h"
@ -217,7 +218,7 @@ void DialogInsertNode::ShowContextMenu(const QPoint &pos)
QListWidgetItem *rowItem = ui->listWidget->item(row);
SCASSERT(rowItem != nullptr);
QAction *actionDelete = menu->addAction(QIcon::fromTheme(editDeleteIcon), tr("Delete"));
QAction *actionDelete = menu->addAction(FromTheme(VThemeIcon::EditDelete), tr("Delete"));
QAction *selectedAction = menu->exec(ui->listWidget->viewport()->mapToGlobal(pos));
if (selectedAction == actionDelete)

View File

@ -263,7 +263,7 @@ void DialogPiecePath::CheckState()
}
else
{
const QIcon icon = QIcon::fromTheme(QStringLiteral("dialog-warning"));
const QIcon icon = FromTheme(VThemeIcon::DialogWarning);
ui->tabWidget->setTabIcon(tabSeamAllowanceIndex, icon);
}
@ -276,7 +276,7 @@ void DialogPiecePath::CheckState()
}
else
{
const QIcon icon = QIcon::fromTheme(QStringLiteral("dialog-warning"));
const QIcon icon = FromTheme(VThemeIcon::DialogWarning);
ui->tabWidget->setTabIcon(tabControlIndex, icon);
}
@ -292,7 +292,7 @@ void DialogPiecePath::CheckState()
}
else
{
const QIcon icon = QIcon::fromTheme(QStringLiteral("dialog-warning"));
const QIcon icon = FromTheme(VThemeIcon::DialogWarning);
ui->tabWidget->setTabIcon(tabPassmarksIndex, icon);
}
@ -2348,8 +2348,8 @@ auto DialogPiecePath::InitContextMenu(QMenu *menu, const VPieceNode &rowNode) ->
actionExcluded->setChecked(rowNode.IsExcluded());
contextMenu.insert(static_cast<int>(ContextMenuOption::Excluded), actionExcluded);
QAction *actionDelete = menu->addAction(QIcon::fromTheme(QStringLiteral("edit-delete")),
QApplication::translate("DialogSeamAllowance", "Delete"));
QAction *actionDelete =
menu->addAction(FromTheme(VThemeIcon::EditDelete), QApplication::translate("DialogSeamAllowance", "Delete"));
contextMenu.insert(static_cast<int>(ContextMenuOption::Delete), actionDelete);
return contextMenu;

View File

@ -603,7 +603,7 @@ void DialogSeamAllowance::CheckTabPathsState()
m_ftb->SetTabText(TabOrder::Paths,
(isValid && flagMainPathIsValid && isNameAndUUIDValid) ? tr("Paths") : tr("Paths") + '*'_L1);
const QIcon warningIcon = QIcon::fromTheme(QStringLiteral("dialog-warning"));
const QIcon warningIcon = FromTheme(VThemeIcon::DialogWarning);
uiTabPaths->tabWidget->setTabIcon(uiTabPaths->tabWidget->indexOf(uiTabPaths->tabSeamAllowance),
isValid ? QIcon() : warningIcon);
@ -641,7 +641,7 @@ void DialogSeamAllowance::CheckTabPassmarksState()
m_ftb->SetTabText(TabOrder::Passmarks, tr("Passmarks") + (allFormulasValid ? QString() : QChar('*')));
const QIcon icon = QIcon::fromTheme(QStringLiteral("dialog-warning"));
const QIcon icon = FromTheme(VThemeIcon::DialogWarning);
uiTabPassmarks->tabWidget->setTabIcon(uiTabPassmarks->tabWidget->indexOf(uiTabPassmarks->tabManualShape),
allFormulasValid ? QIcon() : icon);
@ -670,7 +670,7 @@ void DialogSeamAllowance::CheckTabFoldLineState()
m_ftb->SetTabText(TabOrder::FoldLine, tr("Fold line") + (allFormulasValid ? QString() : QChar('*')));
const QIcon icon = QIcon::fromTheme(QStringLiteral("dialog-warning"));
const QIcon icon = FromTheme(VThemeIcon::DialogWarning);
uiTabFoldLine->tabWidget->setTabIcon(uiTabFoldLine->tabWidget->indexOf(uiTabFoldLine->tabShape),
allFormulasValid ? QIcon() : icon);
}
@ -1205,7 +1205,7 @@ void DialogSeamAllowance::ShowCustomSAContextMenu(const QPoint &pos)
}
QScopedPointer<QMenu> const menu(new QMenu());
QAction *actionOption = menu->addAction(QIcon::fromTheme(preferencesOtherIcon), tr("Options"));
QAction *actionOption = menu->addAction(FromTheme(VThemeIcon::PreferencesOther), tr("Options"));
QListWidgetItem *rowItem = uiTabPaths->listWidgetCustomSA->item(row);
SCASSERT(rowItem != nullptr);
@ -1215,7 +1215,7 @@ void DialogSeamAllowance::ShowCustomSAContextMenu(const QPoint &pos)
actionReverse->setCheckable(true);
actionReverse->setChecked(record.reverse);
QAction *actionDelete = menu->addAction(QIcon::fromTheme(editDeleteIcon), tr("Delete"));
QAction *actionDelete = menu->addAction(FromTheme(VThemeIcon::EditDelete), tr("Delete"));
QAction *selectedAction = menu->exec(uiTabPaths->listWidgetCustomSA->viewport()->mapToGlobal(pos));
if (selectedAction == actionDelete)
@ -1257,8 +1257,8 @@ void DialogSeamAllowance::ShowInternalPathsContextMenu(const QPoint &pos)
}
QScopedPointer<QMenu> const menu(new QMenu());
QAction *actionOption = menu->addAction(QIcon::fromTheme(preferencesOtherIcon), tr("Options"));
QAction *actionDelete = menu->addAction(QIcon::fromTheme(editDeleteIcon), tr("Delete"));
QAction *actionOption = menu->addAction(FromTheme(VThemeIcon::PreferencesOther), tr("Options"));
QAction *actionDelete = menu->addAction(FromTheme(VThemeIcon::EditDelete), tr("Delete"));
QAction *selectedAction = menu->exec(uiTabPaths->listWidgetInternalPaths->viewport()->mapToGlobal(pos));
if (selectedAction == actionDelete)
@ -1292,7 +1292,7 @@ void DialogSeamAllowance::ShowPinsContextMenu(const QPoint &pos)
}
QScopedPointer<QMenu> const menu(new QMenu());
QAction *actionDelete = menu->addAction(QIcon::fromTheme(editDeleteIcon), tr("Delete"));
QAction *actionDelete = menu->addAction(FromTheme(VThemeIcon::EditDelete), tr("Delete"));
QAction *selectedAction = menu->exec(uiTabPins->listWidgetPins->viewport()->mapToGlobal(pos));
if (selectedAction == actionDelete)
@ -1341,7 +1341,7 @@ void DialogSeamAllowance::ShowPlaceLabelsContextMenu(const QPoint &pos)
UpdateCurrentPlaceLabelRecords();
};
QAction *actionOption = menu->addAction(QIcon::fromTheme(preferencesOtherIcon), tr("Options"));
QAction *actionOption = menu->addAction(FromTheme(VThemeIcon::PreferencesOther), tr("Options"));
menu->addSeparator();
QAction *actionSegment = InitAction(tr("Segment"), PlaceLabelType::Segment);
QAction *actionRectangle = InitAction(tr("Rectangle"), PlaceLabelType::Rectangle);
@ -1354,7 +1354,7 @@ void DialogSeamAllowance::ShowPlaceLabelsContextMenu(const QPoint &pos)
QAction *actionButton = InitAction(tr("Button"), PlaceLabelType::Button);
QAction *actionCircle = InitAction(tr("Circle"), PlaceLabelType::Circle);
menu->addSeparator();
QAction *actionDelete = menu->addAction(QIcon::fromTheme(editDeleteIcon), tr("Delete"));
QAction *actionDelete = menu->addAction(FromTheme(VThemeIcon::EditDelete), tr("Delete"));
QAction *selectedAction = menu->exec(uiTabPlaceLabels->listWidgetPlaceLabels->viewport()->mapToGlobal(pos));
if (selectedAction == actionDelete)
@ -2210,7 +2210,7 @@ void DialogSeamAllowance::UpdateDetailLabelValues()
if (not flagDLAngle || not(flagDLFormulas || flagDPin) || not flagPLAngle || not(flagPLFormulas || flagPPin))
{
m_ftb->SetTabText(TabOrder::Labels, tr("Labels") + '*');
const QIcon icon = QIcon::fromTheme(QStringLiteral("dialog-warning"));
const QIcon icon = FromTheme(VThemeIcon::DialogWarning);
uiTabLabels->tabWidget->setTabIcon(uiTabLabels->tabWidget->indexOf(uiTabLabels->tabLabels), icon);
}
else
@ -2293,7 +2293,7 @@ void DialogSeamAllowance::UpdatePatternLabelValues()
if (not flagDLAngle || not(flagDLFormulas || flagDPin) || not flagPLAngle || not(flagPLFormulas || flagPPin))
{
m_ftb->SetTabText(TabOrder::Labels, tr("Labels") + '*');
const QIcon icon = QIcon::fromTheme(QStringLiteral("dialog-warning"));
const QIcon icon = FromTheme(VThemeIcon::DialogWarning);
uiTabLabels->tabWidget->setTabIcon(uiTabLabels->tabWidget->indexOf(uiTabLabels->tabLabels), icon);
}
else
@ -3177,7 +3177,7 @@ void DialogSeamAllowance::DetailPinPointChanged()
topPinId == NULL_ID &&bottomPinId == NULL_ID ? color = OkColor(this) : color = errorColor;
m_ftb->SetTabText(TabOrder::Labels, tr("Labels") + '*');
const QIcon icon = QIcon::fromTheme(QStringLiteral("dialog-warning"));
const QIcon icon = FromTheme(VThemeIcon::DialogWarning);
uiTabLabels->tabWidget->setTabIcon(uiTabLabels->tabWidget->indexOf(uiTabLabels->tabLabels), icon);
}
EnableDetailLabelFormulaControls(not flagDPin);
@ -3210,7 +3210,7 @@ void DialogSeamAllowance::PatternPinPointChanged()
topPinId == NULL_ID &&bottomPinId == NULL_ID ? color = OkColor(this) : color = errorColor;
m_ftb->SetTabText(TabOrder::Labels, tr("Labels") + '*');
const QIcon icon = QIcon::fromTheme(QStringLiteral("dialog-warning"));
const QIcon icon = FromTheme(VThemeIcon::DialogWarning);
uiTabLabels->tabWidget->setTabIcon(uiTabLabels->tabWidget->indexOf(uiTabLabels->tabLabels), icon);
}
EnablePatternLabelFormulaControls(not flagPPin);
@ -5383,7 +5383,7 @@ auto DialogSeamAllowance::InitMainPathContextMenu(QMenu *menu, const VPieceNode
contextMenu.insert(static_cast<int>(MainPathContextMenuOption::Excluded), actionExcluded);
QAction *actionDelete =
menu->addAction(QIcon::fromTheme(editDeleteIcon), QApplication::translate("DialogSeamAllowance", "Delete"));
menu->addAction(FromTheme(VThemeIcon::EditDelete), QApplication::translate("DialogSeamAllowance", "Delete"));
contextMenu.insert(static_cast<int>(MainPathContextMenuOption::Delete), actionDelete);
return contextMenu;

View File

@ -27,34 +27,35 @@
*************************************************************************/
#include "vbackgroundimageitem.h"
#include "../vmisc/vabstractvalapplication.h"
#include "../vwidgets/vmaingraphicsview.h"
#include "../ifc/xml/vabstractpattern.h"
#include "../../undocommands/image/movebackgroundimage.h"
#include "../../undocommands/image/hidebackgroundimage.h"
#include "../../undocommands/image/holdbackgroundimage.h"
#include "../../undocommands/image/movebackgroundimage.h"
#include "../../undocommands/image/opaquebackgroundimage.h"
#include "../../undocommands/image/renamebackgroundimage.h"
#include "../../undocommands/image/resetbackgroundimage.h"
#include "../../undocommands/image/rotatebackgroundimage.h"
#include "../../undocommands/image/scalebackgroundimage.h"
#include "../../undocommands/image/renamebackgroundimage.h"
#include "../../undocommands/image/hidebackgroundimage.h"
#include "../../undocommands/image/resetbackgroundimage.h"
#include "../../undocommands/image/opaquebackgroundimage.h"
#include "../../undocommands/image/zvaluemovebackgroundimage.h"
#include "../ifc/xml/vabstractpattern.h"
#include "../toolsdef.h"
#include "../vmisc/theme/themeDef.h"
#include "../vmisc/vabstractvalapplication.h"
#include "../vwidgets/vmaingraphicsview.h"
#include <QUndoStack>
#include <QGraphicsView>
#include <QGraphicsSceneMouseEvent>
#include <QMenu>
#include <QGraphicsDropShadowEffect>
#include <QMessageBox>
#include <QGraphicsSceneMouseEvent>
#include <QGraphicsView>
#include <QKeyEvent>
#include <QMenu>
#include <QMessageBox>
#include <QUndoStack>
//---------------------------------------------------------------------------------------------------------------------
VBackgroundImageItem::VBackgroundImageItem(const VBackgroundPatternImage &image, VAbstractPattern *doc,
QGraphicsItem *parent)
: QGraphicsObject{parent},
m_image(image),
m_doc(doc)
: QGraphicsObject{parent},
m_image(image),
m_doc(doc)
{
SCASSERT(doc != nullptr)
@ -176,7 +177,7 @@ void VBackgroundImageItem::PositionChanged(QUuid id)
QTransform const newMatrix = m_image.Matrix();
if (not VFuzzyComparePossibleNulls(oldMatrix.m31(), newMatrix.m31()) ||
not VFuzzyComparePossibleNulls(oldMatrix.m32(), newMatrix.m32()))
not VFuzzyComparePossibleNulls(oldMatrix.m32(), newMatrix.m32()))
{
prepareGeometryChange();
update();
@ -352,7 +353,7 @@ void VBackgroundImageItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
void VBackgroundImageItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
if (event->button() == Qt::LeftButton && event->type() != QEvent::GraphicsSceneMouseDoubleClick &&
(flags() & QGraphicsItem::ItemIsMovable))
(flags() & QGraphicsItem::ItemIsMovable))
{
m_lastMoveDistance = QPointF();
SetItemOverrideCursor(this, cursorArrowOpenHand, 1, 1);
@ -422,16 +423,16 @@ void VBackgroundImageItem::contextMenuEvent(QGraphicsSceneContextMenuEvent *even
actionVisible->setCheckable(true);
actionVisible->setChecked(m_image.Visible());
#if defined(Q_OS_MAC)
#if defined(Q_OS_MAC)
const QString actionShowTitle = tr("Show in Finder");
#else
const QString actionShowTitle = tr("Show in Explorer");
#endif
QAction *actionShow = menu.addAction(QIcon::fromTheme(QStringLiteral("system-search")), actionShowTitle);
QAction *actionShow = menu.addAction(FromTheme(VThemeIcon::SystemSearch), actionShowTitle);
actionShow->setVisible(false);
actionShow->setEnabled(QFileInfo::exists(m_image.FilePath()));
QAction *actionSaveAs = menu.addAction(QIcon::fromTheme(QStringLiteral("document-save-as")), tr("Save as …"));
QAction *actionSaveAs = menu.addAction(FromTheme(VThemeIcon::DocumentSaveAs), tr("Save as …"));
actionSaveAs->setVisible(false);
if (not m_image.FilePath().isEmpty())
@ -446,7 +447,7 @@ void VBackgroundImageItem::contextMenuEvent(QGraphicsSceneContextMenuEvent *even
QAction *actionReset = menu.addAction(tr("Reset transformation"));
actionReset->setEnabled(not m_image.Hold());
QAction *actionRemove = menu.addAction(QIcon::fromTheme(QStringLiteral("edit-delete")), tr("Delete"));
QAction *actionRemove = menu.addAction(FromTheme(VThemeIcon::EditDelete), tr("Delete"));
QAction *selectedAction = menu.exec(event->screenPos());
if (selectedAction == holdOption)
@ -481,16 +482,16 @@ void VBackgroundImageItem::keyPressEvent(QKeyEvent *event)
const int move = (event->modifiers() & Qt::ShiftModifier) ? 10 : 1;
int angle = 15;
if(event->modifiers() & Qt::ControlModifier)
if (event->modifiers() & Qt::ControlModifier)
{
angle = 90;
}
else if(event->modifiers() & Qt::AltModifier)
else if (event->modifiers() & Qt::AltModifier)
{
angle = 1;
}
switch(event->key())
switch (event->key())
{
case Qt::Key_Left:
TranslateImageOn(-move, 0);
@ -557,16 +558,10 @@ void VBackgroundImageItem::keyReleaseEvent(QKeyEvent *event)
return;
}
}
else if (event->key() == Qt::Key_Left ||
event->key() == Qt::Key_Right ||
event->key() == Qt::Key_Up ||
event->key() == Qt::Key_Down ||
event->key() == Qt::Key_BracketLeft ||
event->key() == Qt::Key_BracketRight ||
event->key() == Qt::Key_Period ||
event->key() == Qt::Key_Greater ||
event->key() == Qt::Key_Comma ||
event->key() == Qt::Key_Less)
else if (event->key() == Qt::Key_Left || event->key() == Qt::Key_Right || event->key() == Qt::Key_Up ||
event->key() == Qt::Key_Down || event->key() == Qt::Key_BracketLeft ||
event->key() == Qt::Key_BracketRight || event->key() == Qt::Key_Period ||
event->key() == Qt::Key_Greater || event->key() == Qt::Key_Comma || event->key() == Qt::Key_Less)
{
if (not event->isAutoRepeat())
{
@ -612,7 +607,7 @@ void VBackgroundImageItem::UpdateHoldState()
m_image = m_doc->GetBackgroundImage(m_image.Id());
setFlag(QGraphicsItem::ItemIsMovable, not m_image.Hold());
setFlag(QGraphicsItem::ItemSendsGeometryChanges, not m_image.Hold());
setFlag(QGraphicsItem::ItemIsFocusable, not m_image.Hold());// For keyboard input focus
setFlag(QGraphicsItem::ItemIsFocusable, not m_image.Hold()); // For keyboard input focus
emit UpdateControls();
}
@ -644,7 +639,7 @@ void VBackgroundImageItem::InitImage()
setFlag(QGraphicsItem::ItemIsMovable, not m_image.Hold());
setFlag(QGraphicsItem::ItemSendsGeometryChanges, not m_image.Hold());
setFlag(QGraphicsItem::ItemIsFocusable, not m_image.Hold());// For keyboard input focus
setFlag(QGraphicsItem::ItemIsFocusable, not m_image.Hold()); // For keyboard input focus
setVisible(m_image.Visible());
}

View File

@ -183,16 +183,14 @@ void VDrawTool::ContextMenu(QGraphicsSceneContextMenuEvent *event, quint32 itemI
qCDebug(vTool, "Creating tool context menu.");
QMenu menu;
QAction *actionOption =
menu.addAction(QIcon::fromTheme(QStringLiteral("preferences-other")), VDrawTool::tr("Options"));
QAction *actionOption = menu.addAction(FromTheme(VThemeIcon::PreferencesOther), VDrawTool::tr("Options"));
// add the menu "add to group" to the context menu
QMap<quint32, QString> groupsNotContainingItem = doc->GetGroupsContainingItem(this->getId(), itemId, false);
auto *actionsAddToGroup = new QActionGroup(this);
if (not groupsNotContainingItem.empty())
{
QMenu *menuAddToGroup =
menu.addMenu(QIcon::fromTheme(QStringLiteral("list-add")), VDrawTool::tr("Add to group"));
QMenu *menuAddToGroup = menu.addMenu(FromTheme(VThemeIcon::ListAdd), VDrawTool::tr("Add to group"));
QStringList list = QStringList(groupsNotContainingItem.values());
list.sort(Qt::CaseInsensitive);
@ -216,7 +214,7 @@ void VDrawTool::ContextMenu(QGraphicsSceneContextMenuEvent *event, quint32 itemI
if (not groupsContainingItem.empty())
{
QMenu *menuRemoveFromGroup =
menu.addMenu(QIcon::fromTheme(QStringLiteral("list-remove")), VDrawTool::tr("Remove from group"));
menu.addMenu(FromTheme(VThemeIcon::ListRemove), VDrawTool::tr("Remove from group"));
QStringList list = QStringList(groupsContainingItem.values());
list.sort(Qt::CaseInsensitive);
@ -246,7 +244,7 @@ void VDrawTool::ContextMenu(QGraphicsSceneContextMenuEvent *event, quint32 itemI
QAction *actionRestoreLabelPosition = menu.addAction(VDrawTool::tr("Restore label position"));
actionRestoreLabelPosition->setVisible(itemType == GOType::Point);
QAction *actionRemove = menu.addAction(QIcon::fromTheme(QStringLiteral("edit-delete")), VDrawTool::tr("Delete"));
QAction *actionRemove = menu.addAction(FromTheme(VThemeIcon::EditDelete), VDrawTool::tr("Delete"));
if (showRemove == RemoveOption::Enable)
{
if (ref == Referens::Follow)

View File

@ -331,9 +331,9 @@ auto VNodePoint::InitContextMenu(QMenu *menu, vidtype pieceId, quint32 referens)
separatorAct->setSeparator(true);
menu->addAction(separatorAct);
contextMenu.insert(static_cast<int>(ContextMenuOption::Option),
menu->addAction(QIcon::fromTheme(QStringLiteral("preferences-other")),
QCoreApplication::translate("VNodePoint", "Options")));
contextMenu.insert(
static_cast<int>(ContextMenuOption::Option),
menu->addAction(FromTheme(VThemeIcon::PreferencesOther), QCoreApplication::translate("VNodePoint", "Options")));
const VPiece detail = VAbstractTool::data.GetPiece(pieceId);
@ -370,8 +370,8 @@ auto VNodePoint::InitContextMenu(QMenu *menu, vidtype pieceId, quint32 referens)
reseteLabelTemplateOption->setEnabled(not doc->GetDefaultPieceLabelPath().isEmpty());
contextMenu.insert(static_cast<int>(ContextMenuOption::ResetLabelTemplate), reseteLabelTemplateOption);
QAction *actionRemove = menu->addAction(QIcon::fromTheme(QStringLiteral("edit-delete")),
QCoreApplication::translate("VNodePoint", "Delete"));
QAction *actionRemove =
menu->addAction(FromTheme(VThemeIcon::EditDelete), QCoreApplication::translate("VNodePoint", "Delete"));
referens > 1 ? actionRemove->setEnabled(false) : actionRemove->setEnabled(true);
contextMenu.insert(static_cast<int>(ContextMenuOption::Remove), actionRemove);

View File

@ -1538,7 +1538,7 @@ void VToolSeamAllowance::contextMenuEvent(QGraphicsSceneContextMenuEvent *event)
}
QMenu menu;
QAction *actionOption = menu.addAction(QIcon::fromTheme(QStringLiteral("preferences-other")), tr("Options"));
QAction *actionOption = menu.addAction(FromTheme(VThemeIcon::PreferencesOther), tr("Options"));
const VPiece detail = VAbstractTool::data.GetPiece(m_id);
@ -1573,7 +1573,7 @@ void VToolSeamAllowance::contextMenuEvent(QGraphicsSceneContextMenuEvent *event)
QAction *reseteLabelTemplateOption = menu.addAction(tr("Reset piece label template"));
reseteLabelTemplateOption->setEnabled(not doc->GetDefaultPieceLabelPath().isEmpty());
QAction *actionRemove = menu.addAction(QIcon::fromTheme(QStringLiteral("edit-delete")), tr("Delete"));
QAction *actionRemove = menu.addAction(FromTheme(VThemeIcon::EditDelete), tr("Delete"));
actionRemove->setDisabled(_referens > 0);
QAction *selectedAction = menu.exec(event->screenPos());