1// Copyright (C) 2023 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
3
4#include "QtGui/qbrush.h"
5#include "utils_p.h"
6
7#include <QtCore/QRegularExpression>
8
9QT_BEGIN_NAMESPACE
10
11Utils::ParamType Utils::preParseFormat(const QString &format, QString &preStr, QString &postStr,
12 int &precision, char &formatSpec)
13{
14 static QRegularExpression formatMatcher(QStringLiteral("^([^%]*)%([\\-\\+#\\s\\d\\.lhjztL]*)([dicuoxfegXFEG])(.*)$"));
15 static QRegularExpression precisionMatcher(QStringLiteral("\\.(\\d+)"));
16
17 Utils::ParamType retVal;
18
19 QRegularExpressionMatch formatMatch = formatMatcher.match(subject: format, offset: 0);
20
21 if (formatMatch.hasMatch()) {
22 preStr = formatMatch.captured(nth: 1);
23 // Six and 'g' are defaults in Qt API
24 precision = 6;
25 if (!formatMatch.captured(nth: 2).isEmpty()) {
26 QRegularExpressionMatch precisionMatch = precisionMatcher.match(subject: formatMatch.captured(nth: 2),
27 offset: 0);
28 if (precisionMatch.hasMatch())
29 precision = precisionMatch.captured(nth: 1).toInt();
30 }
31 if (formatMatch.captured(nth: 3).isEmpty())
32 formatSpec = 'g';
33 else
34 formatSpec = formatMatch.captured(nth: 3).at(i: 0).toLatin1();
35 postStr = formatMatch.captured(nth: 4);
36 retVal = mapFormatCharToParamType(formatSpec);
37 } else {
38 retVal = ParamTypeUnknown;
39 // The out parameters are irrelevant in unknown case
40 }
41
42 return retVal;
43}
44
45Utils::ParamType Utils::mapFormatCharToParamType(char formatSpec)
46{
47 ParamType retVal = ParamTypeUnknown;
48 if (formatSpec == 'd' || formatSpec == 'i' || formatSpec == 'c') {
49 retVal = ParamTypeInt;
50 } else if (formatSpec == 'u' || formatSpec == 'o'
51 || formatSpec == 'x'|| formatSpec == 'X') {
52 retVal = ParamTypeUInt;
53 } else if (formatSpec == 'f' || formatSpec == 'F'
54 || formatSpec == 'e' || formatSpec == 'E'
55 || formatSpec == 'g' || formatSpec == 'G') {
56 retVal = ParamTypeReal;
57 }
58
59 return retVal;
60}
61
62QString Utils::formatLabelSprintf(const QByteArray &format, Utils::ParamType paramType, qreal value)
63{
64 switch (paramType) {
65 case ParamTypeInt:
66 return QString::asprintf(format: format.constData(), qint64(value));
67 case ParamTypeUInt:
68 return QString::asprintf(format: format.constData(), quint64(value));
69 case ParamTypeReal:
70 return QString::asprintf(format: format.constData(), value);
71 default:
72 // Return format string to detect errors. Bars selection label logic also depends on this.
73 return QString::fromUtf8(ba: format);
74 }
75}
76
77QString Utils::formatLabelLocalized(Utils::ParamType paramType, qreal value,
78 const QLocale &locale, const QString &preStr, const QString &postStr,
79 int precision, char formatSpec, const QByteArray &format)
80{
81 switch (paramType) {
82 case ParamTypeInt:
83 case ParamTypeUInt:
84 return preStr + locale.toString(i: qint64(value)) + postStr;
85 case ParamTypeReal:
86 return preStr + locale.toString(f: value, format: formatSpec, precision) + postStr;
87 default:
88 // Return format string to detect errors. Bars selection label logic also depends on this.
89 return QString::fromUtf8(ba: format);
90 }
91}
92
93QString Utils::defaultLabelFormat()
94{
95 static const QString defaultFormat(QStringLiteral("%.2f"));
96 return defaultFormat;
97}
98
99float Utils::wrapValue(float value, float min, float max)
100{
101 if (value > max) {
102 value = min + (value - max);
103
104 // In case single wrap fails, jump to opposite end.
105 if (value > max)
106 value = min;
107 }
108
109 if (value < min) {
110 value = max + (value - min);
111
112 // In case single wrap fails, jump to opposite end.
113 if (value < min)
114 value = max;
115 }
116
117 return value;
118}
119
120QQuaternion Utils::calculateRotation(const QVector3D &xyzRotations)
121{
122 QQuaternion rotQuatX = QQuaternion::fromAxisAndAngle(x: 1.0f, y: 0.0f, z: 0.0f, angle: xyzRotations.x());
123 QQuaternion rotQuatY = QQuaternion::fromAxisAndAngle(x: 0.0f, y: 1.0f, z: 0.0f, angle: xyzRotations.y());
124 QQuaternion rotQuatZ = QQuaternion::fromAxisAndAngle(x: 0.0f, y: 0.0f, z: 1.0f, angle: xyzRotations.z());
125 QQuaternion totalRotation = rotQuatY * rotQuatZ * rotQuatX;
126 return totalRotation;
127}
128
129void Utils::verifyGradientCompleteness(QLinearGradient &gradient)
130{
131 // Fix the start and end stops of the gradient, to make sure it's complete (0...1)
132 auto stops = gradient.stops();
133 if (stops.first().first != 0.) {
134 const QColor firstColor = stops.first().second;
135 gradient.setColorAt(pos: 0., color: firstColor);
136 }
137 if (stops.last().first != 1.) {
138 const QColor lastColor = stops.last().second;
139 gradient.setColorAt(pos: 1., color: lastColor);
140 }
141}
142
143QT_END_NAMESPACE
144

source code of qtgraphs/src/graphs/utils/utils.cpp