Changeset View
Changeset View
Standalone View
Standalone View
src/lib/util/kformatprivate.cpp
Show All 31 Lines | |||||
32 | { | 32 | { | ||
33 | m_locale = locale; | 33 | m_locale = locale; | ||
34 | } | 34 | } | ||
35 | 35 | | |||
36 | KFormatPrivate::~KFormatPrivate() | 36 | KFormatPrivate::~KFormatPrivate() | ||
37 | { | 37 | { | ||
38 | } | 38 | } | ||
39 | 39 | | |||
40 | constexpr double bpow(int exp) { | ||||
41 | return (exp > 0) ? 2.0 * bpow(exp - 1) : | ||||
42 | (exp < 0) ? 0.5 * bpow(exp + 1) : | ||||
43 | 1.0; | ||||
44 | } | ||||
45 | | ||||
46 | QString KFormatPrivate::formatValue(double value, | ||||
47 | KFormat::Unit unit, | ||||
48 | QString unitString, | ||||
49 | int precision, | ||||
50 | KFormat::UnitPrefix prefix, | ||||
51 | KFormat::BinaryUnitDialect dialect) const | ||||
52 | { | ||||
53 | if (dialect <= KFormat::DefaultBinaryDialect || dialect > KFormat::LastBinaryDialect) { | ||||
54 | dialect = KFormat::IECBinaryDialect; | ||||
55 | } | ||||
56 | | ||||
57 | if (static_cast<int>(prefix) < static_cast<int>(KFormat::UnitPrefix::Yocto) || | ||||
58 | static_cast<int>(prefix) > static_cast<int>(KFormat::UnitPrefix::Yotta)) { | ||||
59 | prefix = KFormat::UnitPrefix::AutoAdjust; | ||||
60 | } | ||||
61 | | ||||
62 | double multiplier = 1024.0; | ||||
63 | if (dialect == KFormat::MetricBinaryDialect) { | ||||
64 | multiplier = 1000.0; | ||||
65 | } | ||||
66 | | ||||
67 | int power = 0; | ||||
68 | if (prefix == KFormat::UnitPrefix::AutoAdjust) { | ||||
69 | double adjustValue = qAbs(value); | ||||
70 | while (adjustValue >= multiplier) { | ||||
71 | adjustValue /= multiplier; | ||||
72 | power += 1; | ||||
73 | } | ||||
74 | while (adjustValue && adjustValue < 1.0) { | ||||
75 | adjustValue *= multiplier; | ||||
76 | power -= 1; | ||||
77 | } | ||||
78 | const KFormat::UnitPrefix map[] = { | ||||
79 | KFormat::UnitPrefix::Yocto, // -8 | ||||
80 | KFormat::UnitPrefix::Zepto, | ||||
81 | KFormat::UnitPrefix::Atto, | ||||
82 | KFormat::UnitPrefix::Femto, | ||||
83 | KFormat::UnitPrefix::Pico, | ||||
84 | KFormat::UnitPrefix::Nano, | ||||
85 | KFormat::UnitPrefix::Micro, | ||||
86 | KFormat::UnitPrefix::Mili, | ||||
87 | KFormat::UnitPrefix::Unity, // 0 | ||||
88 | KFormat::UnitPrefix::Kilo, | ||||
89 | KFormat::UnitPrefix::Mega, | ||||
90 | KFormat::UnitPrefix::Giga, | ||||
91 | KFormat::UnitPrefix::Tera, | ||||
92 | KFormat::UnitPrefix::Peta, | ||||
93 | KFormat::UnitPrefix::Exa, | ||||
94 | KFormat::UnitPrefix::Zetta, | ||||
95 | KFormat::UnitPrefix::Yotta, // 8 | ||||
96 | }; | ||||
97 | power = std::max(-8, std::min(8, power)); | ||||
98 | prefix = map[power + 8]; | ||||
99 | } | ||||
100 | | ||||
101 | if (prefix == KFormat::UnitPrefix::Unity && | ||||
102 | unit == KFormat::Unit::Byte) { | ||||
103 | precision = 0; | ||||
104 | } | ||||
105 | | ||||
106 | struct PrefixMapEntry | ||||
107 | { | ||||
108 | KFormat::UnitPrefix prefix; | ||||
109 | double decimalFactor; | ||||
110 | double binaryFactor; | ||||
111 | QChar prefixChar; | ||||
112 | }; | ||||
113 | | ||||
114 | const PrefixMapEntry map[] = { | ||||
115 | { KFormat::UnitPrefix::Yocto, 1e-24, bpow(-80), u'y' }, | ||||
116 | { KFormat::UnitPrefix::Zepto, 1e-21, bpow(-70), u'z' }, | ||||
117 | { KFormat::UnitPrefix::Atto, 1e-18, bpow(-60), u'a' }, | ||||
118 | { KFormat::UnitPrefix::Femto, 1e-15, bpow(-50), u'f' }, | ||||
119 | { KFormat::UnitPrefix::Pico, 1e-12, bpow(-40), u'p' }, | ||||
120 | { KFormat::UnitPrefix::Nano, 1e-9, bpow(-30), u'n' }, | ||||
121 | { KFormat::UnitPrefix::Micro, 1e-6, bpow(-20), u'µ' }, | ||||
122 | { KFormat::UnitPrefix::Mili, 1e-3, bpow(-10), u'm' }, | ||||
123 | { KFormat::UnitPrefix::Unity, 1.0, 1.0, u'\0' }, | ||||
124 | { KFormat::UnitPrefix::Kilo, 1e3, bpow(10), u'k' }, | ||||
125 | { KFormat::UnitPrefix::Mega, 1e6, bpow(20), u'M' }, | ||||
126 | { KFormat::UnitPrefix::Giga, 1e9, bpow(30), u'G' }, | ||||
127 | { KFormat::UnitPrefix::Tera, 1e12, bpow(40), u'T' }, | ||||
128 | { KFormat::UnitPrefix::Peta, 1e15, bpow(50), u'P' }, | ||||
129 | { KFormat::UnitPrefix::Exa, 1e18, bpow(60), u'E' }, | ||||
130 | { KFormat::UnitPrefix::Zetta, 1e21, bpow(70), u'Z' }, | ||||
131 | { KFormat::UnitPrefix::Yotta, 1e24, bpow(80), u'Y' }, | ||||
132 | }; | ||||
133 | | ||||
134 | auto entry = std::find_if(std::begin(map), std::end(map), | ||||
135 | [prefix](const PrefixMapEntry& e) { return e.prefix == prefix; }); | ||||
136 | | ||||
137 | switch (unit) { | ||||
138 | case KFormat::Unit::Bit: | ||||
139 | unitString = QStringLiteral("bit"); | ||||
140 | break; | ||||
141 | case KFormat::Unit::Byte: | ||||
142 | unitString = QStringLiteral("B"); | ||||
143 | break; | ||||
144 | case KFormat::Unit::Meter: | ||||
145 | unitString = QStringLiteral("m"); | ||||
kossebau: Are we sure those unit symbols do not need to be localized? What about languages using… | |||||
Yes. As you said, these are symbols. For the names there may be transliterations, the symbols stay the same, to avoid ambiguities. This also matches my experience with datasheets, the text may be chinese, but measurements are given in SI units. bruns: Yes. As you said, these are symbols. For the names there may be transliterations, the symbols… | |||||
146 | break; | ||||
147 | case KFormat::Unit::Hertz: | ||||
148 | unitString = QStringLiteral("Hz"); | ||||
149 | break; | ||||
150 | case KFormat::Unit::Other: | ||||
151 | break; | ||||
152 | } | ||||
153 | | ||||
154 | if (prefix == KFormat::UnitPrefix::Unity) { | ||||
Please use multi-argument arg method with string arguments: arg(numString).arg(unitString) -> arg(prefixString, unitString) kossebau: Please use multi-argument arg method with string arguments: arg(numString).arg(unitString) ->… | |||||
155 | QString numString = m_locale.toString(value, 'f', precision); | ||||
156 | //: value without prefix, format "<val> <unit>" | ||||
157 | return tr("%1 %2", "no Prefix").arg(numString, unitString); | ||||
158 | } | ||||
159 | | ||||
160 | QString prefixString; | ||||
161 | if (dialect == KFormat::MetricBinaryDialect) { | ||||
162 | value /= entry->decimalFactor; | ||||
163 | prefixString = entry->prefixChar; | ||||
164 | } else { | ||||
165 | value /= entry->binaryFactor; | ||||
166 | prefixString = QString(entry->prefixChar).toUpper(); | ||||
167 | if (dialect == KFormat::IECBinaryDialect) { | ||||
168 | prefixString += u'i'; | ||||
169 | } | ||||
170 | } | ||||
171 | | ||||
172 | QString numString = m_locale.toString(value, 'f', precision); | ||||
kossebau: arg(prefixString, unitString) | |||||
173 | | ||||
174 | //: value with prefix, format "<val> <prefix><unit>" | ||||
175 | return tr("%1 %2%3", "MetricBinaryDialect").arg(numString, prefixString, unitString); | ||||
176 | } | ||||
177 | | ||||
40 | QString KFormatPrivate::formatByteSize(double size, int precision, | 178 | QString KFormatPrivate::formatByteSize(double size, int precision, | ||
41 | KFormat::BinaryUnitDialect dialect, KFormat::BinarySizeUnits units) const | 179 | KFormat::BinaryUnitDialect dialect, KFormat::BinarySizeUnits units) const | ||
42 | { | 180 | { | ||
43 | // Current KDE default is IECBinaryDialect | 181 | // Current KDE default is IECBinaryDialect | ||
44 | if (dialect <= KFormat::DefaultBinaryDialect || dialect > KFormat::LastBinaryDialect) { | 182 | if (dialect <= KFormat::DefaultBinaryDialect || dialect > KFormat::LastBinaryDialect) { | ||
45 | dialect = KFormat::IECBinaryDialect; | 183 | dialect = KFormat::IECBinaryDialect; | ||
46 | } | 184 | } | ||
47 | 185 | | |||
▲ Show 20 Lines • Show All 391 Lines • Show Last 20 Lines |
Are we sure those unit symbols do not need to be localized? What about languages using different scripts (cyrillic, chinese, arabic, etc)?