diff --git a/autotests/propertyinfotest.cpp b/autotests/propertyinfotest.cpp --- a/autotests/propertyinfotest.cpp +++ b/autotests/propertyinfotest.cpp @@ -133,6 +133,14 @@ { Property::PhotoExposureTime, true, 0.0015625, QStringLiteral("1/640 s")}, { Property::PhotoExposureTime, true, 0.5, QStringLiteral("0.5 s")}, { Property::PhotoExposureTime, true, 0.15, QStringLiteral("0.15 s")}, + { Property::PhotoExposureBiasValue, true, 0.33333, QStringLiteral("1/3 EV")}, + { Property::PhotoExposureBiasValue, true, 0.66667, QStringLiteral("2/3 EV")}, + { Property::PhotoExposureBiasValue, true, 1, QStringLiteral("1 EV")}, + { Property::PhotoExposureBiasValue, true, 1.66667, QStringLiteral("1 2/3 EV")}, + { Property::PhotoExposureBiasValue, true, 0.1888, QStringLiteral("0.189 EV")}, + { Property::PhotoExposureBiasValue, true, -0.33333, QStringLiteral("-1/3 EV")}, + { Property::PhotoExposureBiasValue, true, 0, QStringLiteral("0 EV")}, + { Property::PhotoExposureBiasValue, true, -1.5, QStringLiteral("-1 1/2 EV")}, { Property::PhotoFNumber, true, 4.0, QStringLiteral("f/4")}, { Property::PhotoFNumber, true, 2.8, QStringLiteral("f/2.8")}, { Property::ReplayGainAlbumGain, true, -9.90, QStringLiteral("-9.9")}, diff --git a/src/formatstrings.cpp b/src/formatstrings.cpp --- a/src/formatstrings.cpp +++ b/src/formatstrings.cpp @@ -176,6 +176,41 @@ return i18nc("Time period given in seconds", "%1 s", QLocale().toString(value.toDouble(), 'g', 3)); } +QString FormatStrings::formatPhotoExposureBias(const QVariant& value) +{ + QLocale locale; + auto val = value.toDouble(); + /* + * Exposure values are mostly in steps of one half or third. + * Try to construct a rational number from it. + * Output as double when it is not possible. + */ + auto sixthParts = val * 6; + int roundedSixthParts = static_cast(round(sixthParts)); + int fractional = roundedSixthParts % 6; + if (fractional == 0 || abs(sixthParts - roundedSixthParts) > 1e-3) { + return i18nc("Exposure bias/compensation in exposure value (EV)", "%1 EV", locale.toString(val, 'g', 3)); + } else { + int integral = roundedSixthParts / 6; + int nominator = fractional; + int denominator = 6; + if (nominator % 2 == 0) { + nominator = nominator / 2; + denominator = denominator / 2; + } else if (nominator % 3 == 0) { + nominator = nominator / 3; + denominator = denominator / 3; + } + if (integral != 0) { + return i18nc("Exposure compensation given as integral with fraction, in exposure value (EV)", + "%1 %2/%3 EV", locale.toString(integral), locale.toString(abs(nominator)), locale.toString(denominator)); + } else { + return i18nc("Exposure compensation given as rational, in exposure value (EV)", + "%1/%2 EV", locale.toString(nominator), locale.toString(denominator)); + } + } +} + QString FormatStrings::formatAspectRatio(const QVariant& value) { return i18nc("Aspect ratio, normalized to one", "%1:1", QLocale().toString(round(value.toDouble() * 100) / 100)); diff --git a/src/formatstrings_p.h b/src/formatstrings_p.h --- a/src/formatstrings_p.h +++ b/src/formatstrings_p.h @@ -55,6 +55,8 @@ static QString formatPhotoTime(const QVariant& value); + static QString formatPhotoExposureBias(const QVariant& value); + static QString formatAspectRatio(const QVariant& value); static QString formatAsFNumber(const QVariant& value); diff --git a/src/propertyinfo.cpp b/src/propertyinfo.cpp --- a/src/propertyinfo.cpp +++ b/src/propertyinfo.cpp @@ -251,7 +251,7 @@ d->name = QStringLiteral("photoExposureBiasValue"); d->displayName = i18nc("@label EXIF", "Exposure Bias"); d->valueType = QVariant::Double; - d->formatAsString = &FormatStrings::formatDouble; + d->formatAsString = &FormatStrings::formatPhotoExposureBias; break; case Property::PhotoExposureTime: