KFileMetaData

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

KDE's Doxygen guidelines are available online.