summaryrefslogtreecommitdiffstats
path: root/src/corelib
diff options
context:
space:
mode:
authorShawn Rutledge <shawn.rutledge@qt.io>2017-04-10 12:44:20 +0200
committerEdward Welbourne <edward.welbourne@qt.io>2017-06-20 09:53:14 +0000
commit9d23aebb271ea534a66cb3aceb2e63d9a1c870d6 (patch)
treea78a9b2739aabc594e04cb73cae3a81a24c54dd1 /src/corelib
parentccca8c94359e7f07333b710119bfdf00b25b78fd (diff)
Add QLocale::formattedDataSize and consolidate use cases
It should be easier to translate sizes in bytes to human-readable strings consistently rather than having to repeat this code (and the string translations) in various places. The FileDialog in QtQuick.Controls has a use for this, too. [ChangeLog][QtCore][QLocale] Added QLocale::formattedDataSize() for formatting quantities of bytes as kB, MB, GB etc. Done-with: Edward Welbourne <edward.welbourne@qt.io> Change-Id: I27bca146c3eba90fa7a5d52ef6626ce85723e3f0 Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'src/corelib')
-rw-r--r--src/corelib/tools/qlocale.cpp71
-rw-r--r--src/corelib/tools/qlocale.h15
2 files changed, 86 insertions, 0 deletions
diff --git a/src/corelib/tools/qlocale.cpp b/src/corelib/tools/qlocale.cpp
index 5557b5af2d..43d83db835 100644
--- a/src/corelib/tools/qlocale.cpp
+++ b/src/corelib/tools/qlocale.cpp
@@ -61,6 +61,7 @@
#include "qvariant.h"
#include "qstringbuilder.h"
#include "private/qnumeric_p.h"
+#include <cmath>
#ifdef Q_OS_WIN
# include <qt_windows.h>
# include <time.h>
@@ -3781,6 +3782,76 @@ QString QLocale::toCurrencyString(double value, const QString &symbol, int preci
}
/*!
+ \since 5.10
+
+ \enum QLocale::DataSizeFormat
+
+ Specifies the format for representation of data quantities.
+
+ \omitvalue DataSizeBase1000
+ \omitvalue DataSizeSIQuantifiers
+ \value DataSizeIecFormat format using base 1024 and IEC prefixes: KiB, MiB, GiB, ...
+ \value DataSizeTraditionalFormat format using base 1024 and SI prefixes: kB, MB, GB, ...
+ \value DataSizeSIFormat format using base 1000 and SI prefixes: kB, MB, GB, ...
+
+ \sa formattedDataSize()
+*/
+
+/*!
+ \since 5.10
+
+ Converts a size in bytes to a human-readable localized string, expressed in
+ a unit for which the numeric portion is at least 1 but as low as
+ possible. For example if \a bytes is 16384, \a precision is 2, and \a format
+ is \c DataSizeIecFormat (the default), this function returns "16.00 KiB";
+ for 1330409069609 bytes it returns "1.21 GiB"; and so on. If \a format is \c
+ DataSizeIecFormat or \c DataSizeTraditionalFormat, the given number of bytes
+ is divided by a power of 1024, with result less than 1024; for \c
+ DataSizeSIFormat, it is divided by a power of 1000, with result less than
+ 1000. DataSizeIecFormat uses the new IEC standard quantifiers Ki, Mi and so
+ on, whereas DataSizeSIFormat uses and DataSizeTraditionalFormat abuses the
+ older SI quantifiers k, M, etc.
+
+ \sa refresh(), caching()
+*/
+QString QLocale::formattedDataSize(qint64 bytes, int precision, DataSizeFormats format)
+{
+ int power, base = 1000;
+ if (!bytes) {
+ power = 0;
+ } else if (format & DataSizeBase1000) {
+ power = int(std::log10(qAbs(bytes)) / 3);
+ } else { // Compute log2(bytes) / 10:
+ power = int((63 - qCountLeadingZeroBits(quint64(qAbs(bytes)))) / 10);
+ base = 1024;
+ }
+ // Only go to doubles if we'll be using a quantifier:
+ const QString number = power
+ ? toString(bytes / std::pow(double(base), power), 'f', qMin(precision, 3 * power))
+ : toString(bytes);
+
+ // We don't support sizes in units larger than exbibytes because
+ // the number of bytes would not fit into qint64.
+ Q_ASSERT(power <= 6 && power >= 0);
+ QString unit;
+ if (power > 0) {
+ quint16 index, size;
+ if (format & DataSizeSIQuantifiers) {
+ index = d->m_data->m_byte_si_quantified_idx;
+ size = d->m_data->m_byte_si_quantified_size;
+ } else {
+ index = d->m_data->m_byte_iec_quantified_idx;
+ size = d->m_data->m_byte_iec_quantified_size;
+ }
+ unit = getLocaleListData(byte_unit_data + index, size, power - 1);
+ } else {
+ unit = getLocaleData(byte_unit_data + d->m_data->m_byte_idx, d->m_data->m_byte_size);
+ }
+
+ return number + QLatin1Char(' ') + unit;
+}
+
+/*!
\since 4.8
Returns an ordered list of locale names for translation purposes in
diff --git a/src/corelib/tools/qlocale.h b/src/corelib/tools/qlocale.h
index f9482a7e3a..54b1a32946 100644
--- a/src/corelib/tools/qlocale.h
+++ b/src/corelib/tools/qlocale.h
@@ -913,6 +913,19 @@ public:
CurrencyDisplayName
};
+ enum DataSizeFormat {
+ // Single-bit values, for internal use.
+ DataSizeBase1000 = 1, // use factors of 1000 instead of IEC's 1024;
+ DataSizeSIQuantifiers = 2, // use SI quantifiers instead of IEC ones.
+
+ // Flags values for use in API:
+ DataSizeIecFormat = 0, // base 1024, KiB, MiB, GiB, ...
+ DataSizeTraditionalFormat = DataSizeSIQuantifiers, // base 1024, kB, MB, GB, ...
+ DataSizeSIFormat = DataSizeBase1000 | DataSizeSIQuantifiers // base 1000, kB, MB, GB, ...
+ };
+ Q_DECLARE_FLAGS(DataSizeFormats, DataSizeFormat)
+ Q_FLAG(DataSizeFormats)
+
QLocale();
QLocale(const QString &name);
QLocale(Language language, Country country = AnyCountry);
@@ -1045,6 +1058,8 @@ public:
{ return toCurrencyString(double(i), symbol, precision); }
#endif
+ QString formattedDataSize(qint64 bytes, int precision = 2, DataSizeFormats format = DataSizeIecFormat);
+
QStringList uiLanguages() const;
bool operator==(const QLocale &other) const;