valentina/src/libs/vmisc/def.h

845 lines
25 KiB
C++

/************************************************************************
**
** @file def.h
** @author Roman Telezhynskyi <dismine(at)gmail.com>
** @date 11 4, 2015
**
** @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) 2015 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/>.
**
*************************************************************************/
#ifndef DEF_H
#define DEF_H
#include <QtGlobal>
#ifdef Q_OS_WIN
#include <qt_windows.h>
#endif /*Q_OS_WIN*/
#include <QLineF>
#include <QMargins>
#include <QPrinter>
#include <QString>
#include <QStringList>
#include <csignal>
#include "debugbreak.h"
#include "defglobal.h"
template <class T> class QSharedPointer;
// Header <ciso646> is removed in C++20.
#if __cplusplus <= 201703L
#include <ciso646> // and, not, or
#endif
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define COPY_CONSTRUCTOR_IMPL(className) className::className(const className &) = default;
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define COPY_CONSTRUCTOR_IMPL_2(className, baseClassName) className::className(const className &) = default;
// https://stackoverflow.com/questions/75008386/constructor-is-implicitly-deleted-because-its-exception-specification-does-not-m
#if (defined(Q_CC_GNU) && Q_CC_GNU < 1001) && !defined(Q_CC_CLANG)
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define DEF_CONSTRUCTOR(className) \
className() noexcept \
{ \
}
#else
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define DEF_CONSTRUCTOR(className) className() noexcept = default;
#endif
class QComboBox;
class QMarginsF;
class VTranslateMeasurements;
class QGraphicsItem;
constexpr qreal maxSceneSize = ((20.0 * 1000.0) / 25.4) * PrintDPI; // 20 meters in pixels
constexpr qreal defCurveApproximationScale = 0.5;
constexpr qreal minCurveApproximationScale = 0.2;
constexpr qreal maxCurveApproximationScale = 10.0;
constexpr int minLabelFontSize = 5;
constexpr int maxLabelFontSize = 100;
enum class NodeDetail : qint8
{
Contour,
Modeling
};
enum class SceneObject : qint8
{
Point,
Line,
Spline,
Arc,
ElArc,
SplinePath,
Detail,
Unknown
};
enum class MeasurementsType : qint8
{
Multisize,
Individual,
Unknown
};
enum class Unit : qint8
{
Mm = 0,
Cm,
Inch,
Px,
LAST_UNIT_DO_NOT_USE
};
enum class Source : qint8
{
FromGui,
FromFile,
FromTool
};
enum class NodeUsage : bool
{
NotInUse = false,
InUse = true
};
enum class SelectionType : bool
{
ByMousePress,
ByMouseRelease
};
enum class PageOrientation : bool
{
Portrait = true,
Landscape = false
};
enum class Draw : qint8
{
Calculation,
Modeling,
Layout
};
enum class PieceNodeAngle : quint8
{
ByLength = 0,
ByPointsIntersection = 1,
ByFirstEdgeSymmetry = 2,
BySecondEdgeSymmetry = 3,
ByFirstEdgeRightAngle = 4,
BySecondEdgeRightAngle = 5,
ByLengthCurve = 6, // used only in runtime
LAST_ONE_DO_NOT_USE
};
enum class PassmarkLineType : quint8
{
OneLine = 0, // Default
TwoLines = 1,
ThreeLines = 2,
TMark = 3,
ExternalVMark = 4,
InternalVMark = 5,
UMark = 6,
BoxMark = 7,
CheckMark = 8,
LAST_ONE_DO_NOT_USE
};
auto PassmarkLineTypeToString(PassmarkLineType type) -> QString;
auto StringToPassmarkLineType(const QString &value) -> PassmarkLineType;
enum class PassmarkAngleType : quint8
{
Straightforward = 0, // Default
Bisector,
Intersection,
IntersectionOnlyLeft,
IntersectionOnlyRight,
Intersection2,
Intersection2OnlyLeft,
Intersection2OnlyRight,
LAST_ONE_DO_NOT_USE
};
auto PassmarkAngleTypeToString(PassmarkAngleType type) -> QString;
auto StringToPassmarkAngleType(const QString &value) -> PassmarkAngleType;
auto StrToUnits(const QString &unit) -> Unit;
auto UnitsToStr(const Unit &unit, const bool translate = false) -> QString;
enum class PiecePathIncludeType : quint8
{
AsMainPath = 0,
AsCustomSA = 1
};
constexpr unsigned int defFoldLineFontSize{12};
enum class FoldLineType : quint8
{
TwoArrowsTextAbove = 0, // Default
TwoArrowsTextUnder,
TwoArrows,
Text,
ThreeDots,
ThreeX,
None,
LAST_ONE_DO_NOT_USE
};
auto FoldLineTypeToString(FoldLineType type) -> QString;
auto StringToFoldLineType(const QString &value) -> FoldLineType;
enum class PiecePathType : quint8
{
PiecePath = 0,
CustomSeamAllowance = 1,
InternalPath = 2,
Unknown = 3
};
using ToolVisHolderType = int;
enum class Tool : ToolVisHolderType
{
Arrow,
SinglePoint,
DoublePoint,
LinePoint,
AbstractSpline,
Cut,
BasePoint,
EndLine,
Line,
AlongLine,
ShoulderPoint,
Normal,
Bisector,
LineIntersect,
Spline,
CubicBezier,
CutSpline,
CutArc,
Arc,
ArcWithLength,
SplinePath,
CubicBezierPath,
CutSplinePath,
PointOfContact,
Piece,
PiecePath,
NodePoint,
NodeArc,
NodeElArc,
NodeSpline,
NodeSplinePath,
Height,
Triangle,
LineIntersectAxis,
PointOfIntersectionArcs,
PointOfIntersectionCircles,
PointOfIntersectionCurves,
CurveIntersectAxis,
ArcIntersectAxis,
PointOfIntersection,
PointFromCircleAndTangent,
PointFromArcAndTangent,
TrueDarts,
UnionDetails,
Group,
Rotation,
FlippingByLine,
FlippingByAxis,
Move,
Midpoint,
EllipticalArc,
Pin,
InsertNode,
PlaceLabel,
DuplicateDetail,
BackgroundImage,
BackgroundImageControls,
BackgroundPixmapImage,
BackgroundSVGImage,
ArcStart,
ArcEnd,
LAST_ONE_DO_NOT_USE // add new stuffs above this, this constant must be last and never used
};
enum class Vis : ToolVisHolderType
{
ControlPointSpline = static_cast<ToolVisHolderType>(Tool::LAST_ONE_DO_NOT_USE),
GraphicsSimpleTextItem,
SimplePoint,
SimpleCurve,
ScaledLine,
ScaledEllipse,
Line,
Path,
Operation,
ToolAlongLine,
ToolArc,
ToolArcWithLength,
ToolBisector,
ToolCutArc,
ToolEndLine,
ToolHeight,
ToolLine,
ToolLineIntersect,
ToolNormal,
ToolPointOfContact,
ToolPointOfIntersection,
ToolPointOfIntersectionArcs,
ToolPointOfIntersectionCircles,
ToolPointOfIntersectionCurves,
ToolPointFromCircleAndTangent,
ToolPointFromArcAndTangent,
ToolShoulderPoint,
ToolSpline,
ToolCubicBezier,
ToolCubicBezierPath,
ToolTriangle,
ToolCutSpline,
ToolSplinePath,
ToolCutSplinePath,
ToolLineIntersectAxis,
ToolCurveIntersectAxis,
ToolTrueDarts,
ToolRotation,
ToolFlippingByLine,
ToolFlippingByAxis,
ToolMove,
ToolEllipticalArc,
ToolPiece,
ToolPiecePath,
ToolSpecialPoint,
ToolPlaceLabel,
ToolDuplicateDetail,
PieceSpecialPoints,
NoBrush,
CurvePathItem,
GrainlineItem,
PieceItem,
TextGraphicsItem,
ScenePoint,
LAST_ONE_DO_NOT_USE // add new stuffs above this, this constant must be last and never used
};
enum class Layout : ToolVisHolderType
{
GrainlineItem = static_cast<ToolVisHolderType>(Vis::LAST_ONE_DO_NOT_USE),
FoldLineItem,
LAST_ONE_DO_NOT_USE // add new stuffs above this, this constant must be last and never used
};
enum class VarType : qint8
{
Measurement,
MeasurementSeparator,
Increment,
IncrementSeparator,
LineLength,
CurveLength,
CurveCLength,
LineAngle,
CurveAngle,
ArcRadius,
PieceExternalArea,
PieceSeamLineArea,
Unknown
};
enum class IncrementType : qint8
{
Increment,
Separator
};
auto IncrementTypeToString(IncrementType type) -> QString;
auto StringToIncrementType(const QString &value) -> IncrementType;
enum class MeasurementType : qint8
{
Measurement,
Separator
};
auto MeasurementTypeToString(MeasurementType type) -> QString;
auto StringToMeasurementType(const QString &value) -> MeasurementType;
enum class IMD : qint8 // Individual measurement dimension
{
N, // None
X, // height
Y, // size (chest half circumference)
W, // waist half circumference
Z // hip half circumference
};
/* QImage supports a maximum of 32768x32768 px images (signed short).
* This follows from the condition: width * height * colordepth < INT_MAX (4 billion) -> 32768 * 32768 * 4 = 4 billion.
* The second condition is of course that malloc is able to allocate the requested memory.
*
* If you really need bigger images you will have to use another wrapper or split into multiple QImage's.
*/
#define QIMAGE_MAX 32768
/*
* This macros SCASSERT (for Stop and Continue Assert) will break into the debugger on the line of the assert and allow
* you to continue afterwards should you choose to.
* idea: Q_ASSERT no longer pauses debugger - http://qt-project.org/forums/viewthread/13148
* Usefull links:
* 1. What's the difference between __PRETTY_FUNCTION__, __FUNCTION__, __func__? -
* https://stackoverflow.com/questions/4384765/whats-the-difference-between-pretty-function-function-func
*
* 2. Windows Predefined Macros - http://msdn.microsoft.com/library/b0084kay.aspx
*
* 3. Windows DebugBreak function - http://msdn.microsoft.com/en-us/library/ms679297%28VS.85%29.aspx
*
* 4. Continue to debug after failed assertion on Linux? [C/C++] -
* https://stackoverflow.com/questions/1721543/continue-to-debug-after-failed-assertion-on-linux-c-c
*/
#ifndef V_NO_ASSERT
#define SCASSERT(cond) \
if (!(cond)) \
{ \
qCritical("ASSERT: %s in %s (%s:%u)", #cond, Q_FUNC_INFO, __FILE__, __LINE__); \
debug_break(); \
abort(); \
}
#else // define but disable this function if debugging is not set
#define SCASSERT(cond) qt_noop();
#endif /* V_NO_ASSERT */
#ifndef __has_cpp_attribute
#define __has_cpp_attribute(x) 0
#endif
#ifdef Q_OS_MAC
// Fix QT issue on MacOS version 11.0 "Big Sur"
// https://bugreports.qt.io/browse/QTBUG-87014
// Enables layer backing for Big Sur
// Prevents 100% CPU & RAM utilization
//
// The fix at
//
// https://codereview.qt-project.org/c/qt/qtbase/+/322228/3/src/plugins/platforms/cocoa/qnsview_drawing.mm
//
// enables layer backing if we're running on Big Sur OR we're running on
// Catalina AND we were built with the Catalina SDK. Enable layer backing
// here by setting QT_MAC_WANTS_LAYER=1, but only if we're running on Big
// Sur and our version of Qt doesn't have a fix for QTBUG-87014.
// We'll assume that it will be fixed in 5.12.11, 5.15.3, and 6.0.1.
// Feel free to add other versions if needed.
#define MACOS_LAYER_BACKING_AFFECTED \
((QT_VERSION >= QT_VERSION_CHECK(5, 15, 0) && QT_VERSION < QT_VERSION_CHECK(5, 15, 3)) || \
(QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) && QT_VERSION < QT_VERSION_CHECK(6, 0, 1)))
#if MACOS_LAYER_BACKING_AFFECTED
#include <QOperatingSystemVersion>
void MacosEnableLayerBacking();
#endif // MACOS_LAYER_BACKING_AFFECTED
#endif // Q_OS_MAC
// Don't forget to syncronize with XSD schema.
const int userMaterialPlaceholdersQuantity = 20;
auto QPixmapFromCache(const QString &pixmapPath) -> QPixmap;
void SetItemOverrideCursor(QGraphicsItem *item, const QString &pixmapPath, int hotX = -1, int hotY = -1);
//---------------------------------------------------------------------------------------------------------------------
template <typename T> constexpr auto MmToPixel(T val) noexcept -> T
{
return (val / 25.4) * PrintDPI;
}
//---------------------------------------------------------------------------------------------------------------------
template <typename T> constexpr auto CmToPixel(T val) noexcept -> T
{
return ((val * 10.0) / 25.4) * PrintDPI;
}
//---------------------------------------------------------------------------------------------------------------------
template <typename T> constexpr auto InchToPixel(T val) noexcept -> T
{
return val * PrintDPI;
}
//---------------------------------------------------------------------------------------------------------------------
constexpr auto ToPixel(double val, const Unit &unit) noexcept -> double
{
switch (unit)
{
case Unit::Mm:
return MmToPixel(val);
case Unit::Cm:
return CmToPixel(val);
case Unit::Inch:
return InchToPixel(val);
case Unit::Px:
return val;
default:
break;
}
return 0;
}
//---------------------------------------------------------------------------------------------------------------------
template <typename T> constexpr auto PixelToInch(T pix) -> T
{
return pix / PrintDPI;
}
//---------------------------------------------------------------------------------------------------------------------
template <typename T> constexpr auto PixelToMm(T pix) -> T
{
return PixelToInch(pix) * 25.4;
}
//---------------------------------------------------------------------------------------------------------------------
template <typename T> constexpr auto PixelToCm(T pix) -> T
{
return PixelToInch(pix) * 2.54;
}
//---------------------------------------------------------------------------------------------------------------------
constexpr auto FromPixel(double pix, const Unit &unit) -> double
{
switch (unit)
{
case Unit::Mm:
return PixelToMm(pix);
case Unit::Cm:
return PixelToCm(pix);
case Unit::Inch:
return PixelToInch(pix);
case Unit::Px:
return pix;
default:
break;
}
return 0;
}
//---------------------------------------------------------------------------------------------------------------------
template <typename T> constexpr auto Inch2ToPixel2(T val) -> T
{
return val * (PrintDPI * PrintDPI);
}
//---------------------------------------------------------------------------------------------------------------------
template <typename T> constexpr auto Mm2ToPixel2(T val) -> T
{
// There are 0.15500031 square inches in a square centimeter.
return Inch2ToPixel2(val * 0.001550031);
}
//---------------------------------------------------------------------------------------------------------------------
template <typename T> constexpr auto Cm2ToPixel2(T val) -> T
{
// There are 0.15500031 square inches in a square centimeter.
return Inch2ToPixel2(val * 0.15500031);
}
//---------------------------------------------------------------------------------------------------------------------
constexpr auto ToPixel2(double val, const Unit &unit) -> double
{
switch (unit)
{
case Unit::Mm:
return Mm2ToPixel2(val);
case Unit::Cm:
return Cm2ToPixel2(val);
case Unit::Inch:
return Inch2ToPixel2(val);
case Unit::Px:
return val;
default:
break;
}
return 0;
}
//---------------------------------------------------------------------------------------------------------------------
template <typename T> constexpr auto Pixel2ToInch2(T pix) -> T
{
return pix / (PrintDPI * PrintDPI);
}
//---------------------------------------------------------------------------------------------------------------------
template <typename T> constexpr auto Pixel2ToMm2(T pix) -> T
{
// There are 0.15500031 square inches in a square centimeter.
return Pixel2ToInch2(pix) / 0.001550031;
}
//---------------------------------------------------------------------------------------------------------------------
template <typename T> constexpr auto Pixel2ToCm2(T pix) -> T
{
// There are 0.15500031 square inches in a square centimeter.
return Pixel2ToInch2(pix) / 0.15500031;
}
//---------------------------------------------------------------------------------------------------------------------
constexpr auto FromPixel2(double pix, const Unit &unit) -> double
{
switch (unit)
{
case Unit::Mm:
return Pixel2ToMm2(pix);
case Unit::Cm:
return Pixel2ToCm2(pix);
case Unit::Inch:
return Pixel2ToInch2(pix);
case Unit::Px:
return pix;
default:
break;
}
return 0;
}
//---------------------------------------------------------------------------------------------------------------------
constexpr auto UnitConvertor(qreal value, const Unit &from, const Unit &to) -> qreal
{
switch (from)
{
case Unit::Mm:
switch (to)
{
case Unit::Mm:
return value;
case Unit::Cm:
return value / 10.0;
case Unit::Inch:
return value / 10.0 / 2.54;
case Unit::Px:
return (value / 25.4) * PrintDPI;
default:
break;
}
break;
case Unit::Cm:
switch (to)
{
case Unit::Mm:
return value * 10.0;
case Unit::Cm:
return value;
case Unit::Inch:
return value / 2.54;
case Unit::Px:
return ((value * 10.0) / 25.4) * PrintDPI;
default:
break;
}
break;
case Unit::Inch:
switch (to)
{
case Unit::Mm:
return value * 2.54 * 10.0;
case Unit::Cm:
return value * 2.54;
case Unit::Inch:
return value;
case Unit::Px:
return value * PrintDPI;
default:
break;
}
break;
case Unit::Px:
switch (to)
{
case Unit::Mm:
return (value / PrintDPI) * 25.4;
case Unit::Cm:
return ((value / PrintDPI) * 25.4) / 10.0;
case Unit::Inch:
return value / PrintDPI;
case Unit::Px:
return value;
default:
break;
}
break;
default:
break;
}
return 0;
}
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief UnitConvertor Converts the values of the given margin from given unit to the new unit.
* returns a new instand of QMarginsF.
*/
constexpr auto UnitConvertor(const QMarginsF &margins, const Unit &from, const Unit &to)
-> QMarginsF
{
const qreal left = UnitConvertor(margins.left(), from, to);
const qreal top = UnitConvertor(margins.top(), from, to);
const qreal right = UnitConvertor(margins.right(), from, to);
const qreal bottom = UnitConvertor(margins.bottom(), from, to);
return {left, top, right, bottom};
}
void InitLanguages(QComboBox *combobox);
void InitPieceLabelLanguages(QComboBox *combobox);
Q_REQUIRED_RESULT auto SupportedLocales() -> QStringList;
Q_REQUIRED_RESULT auto RelativeMPath(const QString &patternPath, const QString &absoluteMPath) -> QString;
Q_REQUIRED_RESULT auto AbsoluteMPath(const QString &patternPath, const QString &relativeMPath) -> QString;
auto SplitFilePaths(const QString &path) -> QStringList;
auto GetMinPrinterFields(const QSharedPointer<QPrinter> &printer) -> QMarginsF;
auto GetPrinterFields(const QSharedPointer<QPrinter> &printer) -> QMarginsF;
Q_REQUIRED_RESULT auto darkenPixmap(const QPixmap &pixmap) -> QPixmap;
void ShowInGraphicalShell(const QString &filePath);
Q_REQUIRED_RESULT constexpr static inline auto VFuzzyComparePossibleNulls(double p1, double p2) -> bool;
constexpr static inline auto VFuzzyComparePossibleNulls(double p1, double p2) -> bool
{
if (qFuzzyIsNull(p1))
{
return qFuzzyIsNull(p2);
}
if (qFuzzyIsNull(p2))
{
return false;
}
return qFuzzyCompare(p1, p2);
}
/**
* @brief The CustomSA struct contains record about custom seam allowanse (SA).
*/
struct CustomSARecord
{
CustomSARecord()
: startPoint(0),
path(0),
endPoint(0),
reverse(false),
includeType(PiecePathIncludeType::AsCustomSA)
{
}
friend auto operator<<(QDataStream &out, const CustomSARecord &record) -> QDataStream &;
friend auto operator>>(QDataStream &in, CustomSARecord &record) -> QDataStream &;
quint32 startPoint{0};
quint32 path{0};
quint32 endPoint{0};
bool reverse{false};
PiecePathIncludeType includeType{PiecePathIncludeType::AsCustomSA};
private:
static const quint32 streamHeader;
static const quint16 classVersion;
};
Q_DECLARE_METATYPE(CustomSARecord)
Q_DECLARE_TYPEINFO(CustomSARecord, Q_MOVABLE_TYPE); // NOLINT
/****************************************************************************
** This file is derived from code bearing the following notice:
** The sole author of this file, Adam Higerd, has explicitly disclaimed all
** copyright interest and protection for the content within. This file has
** been placed in the public domain according to United States copyright
** statute and case law. In jurisdictions where this public domain dedication
** is not legally recognized, anyone who receives a copy of this file is
** permitted to use, modify, duplicate, and redistribute this file, in whole
** or in part, with no restrictions or conditions. In these jurisdictions,
** this file shall be copyright (C) 2006-2008 by Adam Higerd.
****************************************************************************/
#define QXT_DECLARE_PRIVATE(PUB) \
friend class PUB##Private; \
QxtPrivateInterface<PUB, PUB##Private> qxt_d;
#define QXT_DECLARE_PUBLIC(PUB) friend class PUB;
#define QXT_INIT_PRIVATE(PUB) qxt_d.setPublic(this);
#define QXT_D(PUB) PUB##Private &d = qxt_d()
#define QXT_P(PUB) PUB &p = qxt_p()
QT_WARNING_PUSH
QT_WARNING_DISABLE_GCC("-Wsuggest-final-types")
QT_WARNING_DISABLE_GCC("-Wsuggest-final-methods")
template <typename PUB> class QxtPrivate
{
public:
QxtPrivate()
: qxt_p_ptr(nullptr)
{
}
virtual ~QxtPrivate() {}
inline void QXT_setPublic(PUB *pub) { qxt_p_ptr = pub; }
protected:
inline auto qxt_p() -> PUB & { return *qxt_p_ptr; }
inline auto qxt_p() const -> const PUB & { return *qxt_p_ptr; }
inline auto qxt_ptr() -> PUB * { return qxt_p_ptr; }
inline auto qxt_ptr() const -> const PUB * { return qxt_p_ptr; }
private:
Q_DISABLE_COPY_MOVE(QxtPrivate) // NOLINT
PUB *qxt_p_ptr;
};
// cppcheck-suppress unknownMacro
QT_WARNING_POP
template <typename PUB, typename PVT> class QxtPrivateInterface
{
friend class QxtPrivate<PUB>;
public:
QxtPrivateInterface()
: pvt(new PVT)
{
}
~QxtPrivateInterface() { delete pvt; }
inline void setPublic(PUB *pub) { pvt->QXT_setPublic(pub); }
inline auto operator()() -> PVT & { return *static_cast<PVT *>(pvt); }
inline auto operator()() const -> const PVT & { return *static_cast<PVT *>(pvt); }
inline auto operator->() -> PVT * { return static_cast<PVT *>(pvt); }
inline auto operator->() const -> const PVT * { return static_cast<PVT *>(pvt); }
private:
Q_DISABLE_COPY_MOVE(QxtPrivateInterface) // NOLINT
QxtPrivate<PUB> *pvt;
};
#endif // DEF_H