KFileMetaData

formatstrings.cpp
1 /*
2  SPDX-FileCopyrightText: 2018 Alexander Stippich <[email protected]>
3 
4  SPDX-License-Identifier: LGPL-2.1-or-later
5 */
6 
7 #include "formatstrings_p.h"
8 
9 #include <math.h>
10 #include <QDateTime>
11 #include <KLocalizedString>
12 #include <KFormat>
13 
14 using namespace KFileMetaData;
15 
16 /*
17  * Calculates and returns the number of digits after the
18  * comma to always show three significant digits for use
19  * with KFormat::formatValue.
20  */
21 int threeSignificantDigits(int value)
22 {
23  if (value == 0) {
24  return 0;
25  }
26  int before_decimal_point = static_cast<int>(log10(value > 0 ? value : -value)) % 3;
27  return 2 - before_decimal_point;
28 }
29 
30 QString FormatStrings::toStringFunction(const QVariant& value)
31 {
32  return value.toString();
33 }
34 
35 QString FormatStrings::formatDouble(const QVariant& value)
36 {
37  return QLocale().toString(value.toDouble(),'g',3);
38 }
39 
40 QString FormatStrings::formatDate(const QVariant& value)
41 {
42  KFormat form;
43  QDateTime dt;
44  if (value.type() == QVariant::DateTime) {
45  dt = value.toDateTime();
46  } else {
48  }
49  if (dt.isValid()) {
51  }
52  return QString();
53 }
54 
55 QString FormatStrings::formatDuration(const QVariant& value)
56 {
57  KFormat form;
58  return form.formatDuration(value.toInt() * 1000);
59 }
60 
61 QString FormatStrings::formatBitRate(const QVariant& value)
62 {
63  KFormat form;
64  return i18nc("@label bitrate (per second)", "%1/s", form.formatValue(value.toInt(),
66 }
67 
68 QString FormatStrings::formatSampleRate(const QVariant& value)
69 {
70  KFormat form;
71  return form.formatValue(value.toInt(), KFormat::Unit::Hertz, threeSignificantDigits(value.toInt()), KFormat::UnitPrefix::AutoAdjust, KFormat::MetricBinaryDialect);
72 }
73 
74 QString FormatStrings::formatOrientationValue(const QVariant& value)
75 {
76  QString string;
77  switch (value.toInt()) {
78  case 1: string = i18nc("Description of image orientation", "Unchanged"); break;
79  case 2: string = i18nc("Description of image orientation", "Horizontally flipped"); break;
80  case 3: string = i18nc("Description of image orientation", "180° rotated"); break;
81  case 4: string = i18nc("Description of image orientation", "Vertically flipped"); break;
82  case 5: string = i18nc("Description of image orientation", "Transposed"); break;
83  case 6: string = i18nc("Description of image orientation, counter clock-wise rotated", "90° rotated CCW "); break;
84  case 7: string = i18nc("Description of image orientation", "Transversed"); break;
85  case 8: string = i18nc("Description of image orientation, counter clock-wise rotated", "270° rotated CCW"); break;
86  default:
87  break;
88  }
89  return string;
90 }
91 
92 QString FormatStrings::formatPhotoFlashValue(const QVariant& value)
93 {
94  // copied from exiv2 tags_int.cpp
95  const QMap<int, QString> flashTranslation = {
96  { 0x00, i18nc("Description of photo flash", "No flash") },
97  { 0x01, i18nc("Description of photo flash", "Fired") },
98  { 0x05, i18nc("Description of photo flash", "Fired, return light not detected") },
99  { 0x07, i18nc("Description of photo flash", "Fired, return light detected") },
100  { 0x08, i18nc("Description of photo flash", "Yes, did not fire") },
101  { 0x09, i18nc("Description of photo flash", "Yes, compulsory") },
102  { 0x0d, i18nc("Description of photo flash", "Yes, compulsory, return light not detected") },
103  { 0x0f, i18nc("Description of photo flash", "Yes, compulsory, return light detected") },
104  { 0x10, i18nc("Description of photo flash", "No, compulsory") },
105  { 0x14, i18nc("Description of photo flash", "No, did not fire, return light not detected") },
106  { 0x18, i18nc("Description of photo flash", "No, auto") },
107  { 0x19, i18nc("Description of photo flash", "Yes, auto") },
108  { 0x1d, i18nc("Description of photo flash", "Yes, auto, return light not detected") },
109  { 0x1f, i18nc("Description of photo flash", "Yes, auto, return light detected") },
110  { 0x20, i18nc("Description of photo flash", "No flash function") },
111  { 0x30, i18nc("Description of photo flash", "No, no flash function") },
112  { 0x41, i18nc("Description of photo flash", "Yes, red-eye reduction") },
113  { 0x45, i18nc("Description of photo flash", "Yes, red-eye reduction, return light not detected") },
114  { 0x47, i18nc("Description of photo flash", "Yes, red-eye reduction, return light detected") },
115  { 0x49, i18nc("Description of photo flash", "Yes, compulsory, red-eye reduction") },
116  { 0x4d, i18nc("Description of photo flash", "Yes, compulsory, red-eye reduction, return light not detected") },
117  { 0x4f, i18nc("Description of photo flash", "Yes, compulsory, red-eye reduction, return light detected") },
118  { 0x50, i18nc("Description of photo flash", "No, red-eye reduction") },
119  { 0x58, i18nc("Description of photo flash", "No, auto, red-eye reduction") },
120  { 0x59, i18nc("Description of photo flash", "Yes, auto, red-eye reduction") },
121  { 0x5d, i18nc("Description of photo flash", "Yes, auto, red-eye reduction, return light not detected") },
122  { 0x5f, i18nc("Description of photo flash", "Yes, auto, red-eye reduction, return light detected") }
123  };
124  if (flashTranslation.contains(value.toInt())) {
125  return flashTranslation.value(value.toInt());
126  } else {
127  return i18n("Unknown");
128  }
129 
130 }
131 
132 QString FormatStrings::formatAsDegree(const QVariant& value)
133 {
134  return i18nc("Symbol of degree, no space", "%1°", QLocale().toString(value.toDouble()));
135 }
136 
137 QString FormatStrings::formatAsMeter(const QVariant& value)
138 {
139  KFormat form;
141 }
142 
143 QString FormatStrings::formatAsMilliMeter(const QVariant& value)
144 {
145  return i18nc("Focal length given in mm", "%1 mm", QLocale().toString(value.toDouble(), 'g', 3));
146 }
147 
148 QString FormatStrings::formatAsFrameRate(const QVariant& value)
149 {
150  return i18nc("Symbol of frames per second, with space", "%1 fps", QLocale().toString(round(value.toDouble() * 100) / 100));
151 }
152 
153 QString FormatStrings::formatPhotoTime(const QVariant& value)
154 {
155  auto val = value.toDouble();
156  if (val < 0.3 && !qFuzzyIsNull(val)) {
157  auto reciprocal = 1.0/val;
158  auto roundedReciprocal = round(reciprocal);
159  if (abs(reciprocal - roundedReciprocal) < 1e-3) {
160  return i18nc("Time period given in seconds as rational number, denominator is given", "1/%1 s", roundedReciprocal);
161  }
162  }
163  return i18nc("Time period given in seconds", "%1 s", QLocale().toString(value.toDouble(), 'g', 3));
164 }
165 
166 QString FormatStrings::formatPhotoExposureBias(const QVariant& value)
167 {
168  QLocale locale;
169  auto val = value.toDouble();
170  /*
171  * Exposure values are mostly in steps of one half or third.
172  * Try to construct a rational number from it.
173  * Output as double when it is not possible.
174  */
175  auto sixthParts = val * 6;
176  int roundedSixthParts = static_cast<int>(round(sixthParts));
177  int fractional = roundedSixthParts % 6;
178  if (fractional == 0 || abs(sixthParts - roundedSixthParts) > 1e-3) {
179  return i18nc("Exposure bias/compensation in exposure value (EV)", "%1 EV", locale.toString(val, 'g', 3));
180  }
181  int integral = roundedSixthParts / 6;
182  int nominator = fractional;
183  int denominator = 6;
184  if (nominator % 2 == 0) {
185  nominator = nominator / 2;
186  denominator = denominator / 2;
187  } else if (nominator % 3 == 0) {
188  nominator = nominator / 3;
189  denominator = denominator / 3;
190  }
191  if (integral != 0) {
192  return i18nc("Exposure compensation given as integral with fraction, in exposure value (EV)",
193  "%1 %2/%3 EV", locale.toString(integral), locale.toString(abs(nominator)), locale.toString(denominator));
194  }
195  return i18nc("Exposure compensation given as rational, in exposure value (EV)",
196  "%1/%2 EV", locale.toString(nominator), locale.toString(denominator));
197 }
198 
199 QString FormatStrings::formatAspectRatio(const QVariant& value)
200 {
201  return i18nc("Aspect ratio, normalized to one", "%1:1", QLocale().toString(round(value.toDouble() * 100) / 100));
202 }
203 
204 QString FormatStrings::formatAsFNumber(const QVariant& value)
205 {
206  return i18nc("F number for photographs", "f/%1", QLocale().toString(value.toDouble(), 'g', 2));
207 }
bool contains(const Key &key) const const
const T value(const Key &key, const T &defaultValue) const const
QString formatRelativeDateTime(const QDateTime &dateTime, QLocale::FormatType format) const
QString formatDuration(quint64 msecs, KFormat::DurationFormatOptions options=KFormat::DefaultDuration) const
MetricBinaryDialect
double toDouble(bool *ok) const const
QString i18n(const char *text, const TYPE &arg...)
QVariant::Type type() const const
char * toString(const T &value)
QString toString(qlonglong i) const const
int toInt(bool *ok) const const
QDateTime fromString(const QString &string, Qt::DateFormat format)
LocaleWrapper locale()
QString formatValue(double value, const QString &unit, int precision, KFormat::UnitPrefix prefix, KFormat::BinaryUnitDialect dialect) const
QDateTime toDateTime() const const
bool isValid() const const
QString i18nc(const char *context, const char *text, const TYPE &arg...)
QString toString() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2022 The KDE developers.
Generated on Thu May 26 2022 03:46:07 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.