diff options
author | Fabian Kosmale <fabian.kosmale@qt.io> | 2023-07-17 12:05:44 +0300 |
---|---|---|
committer | Fabian Kosmale <fabian.kosmale@qt.io> | 2023-07-18 09:38:38 +0300 |
commit | 90226018a98befc89ed767a3aae7a8db0e77076d (patch) | |
tree | 8972fd5458862065feb8a7e743ede5be28bae6bd /src/corelib/text/qstringconverter.cpp | |
parent | bc9ad7db6b6a6121919a7c2400f8a11e2a29dda4 (diff) |
Provide QStringConverter equivalent of QTextCodec::availableCodecs
A text editor commonly wants to display a list of codecs that are
supported. With the introduction of the ICU based QStringConverter, that
list is no longer statically known. So provide the necessary
functionality.
Fixes: QTBUG-109104
Change-Id: I9ecf59aa6bcc6fe65c8872cab84affafec4fa362
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Diffstat (limited to 'src/corelib/text/qstringconverter.cpp')
-rw-r--r-- | src/corelib/text/qstringconverter.cpp | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/src/corelib/text/qstringconverter.cpp b/src/corelib/text/qstringconverter.cpp index 7f68c5113e..8857433544 100644 --- a/src/corelib/text/qstringconverter.cpp +++ b/src/corelib/text/qstringconverter.cpp @@ -10,6 +10,7 @@ #include "private/qstringiterator_p.h" #include "private/qtools_p.h" #include "qbytearraymatcher.h" +#include <QtCore/qbytearraylist.h> #if QT_CONFIG(icu) #include <unicode/ucnv.h> @@ -2032,6 +2033,7 @@ const char *QStringConverter::name() const noexcept Returns the canonical name of the encoding this QStringConverter can encode or decode. Returns a nullptr if the converter is not valid. + The returned name is UTF-8 encoded. \sa isValid() */ @@ -2043,6 +2045,8 @@ const char *QStringConverter::name() const noexcept \c{std::nullopt} is returned. Such a name may, none the less, be accepted by the QStringConverter constructor when Qt is built with ICU, if ICU provides a converter with the given name. + + \a name is expected to be UTF-8 encoded. */ std::optional<QStringConverter::Encoding> QStringConverter::encodingForName(const char *name) noexcept { @@ -2163,6 +2167,60 @@ std::optional<QStringConverter::Encoding> QStringConverter::encodingForHtml(QByt return Utf8; } +static qsizetype availableCodecCount() +{ +#if !QT_CONFIG(icu) + return QStringConverter::Encoding::LastEncoding; +#else + /* icu contains also the names of what Qt provides + except for the special Locale one (so add one for it) + */ + return 1 + ucnv_countAvailable(); +#endif +} + +/*! + Returns a list of names of supported codecs. The names returned + by this function can be passed to QStringEncoder's and + QStringDecoder's constructor to create a en- or decoder for + the given codec. + + \note The order of codecs is an internal implementation detail + and not guaranteed to be stable. + */ +QStringList QStringConverter::availableCodecs() +{ + auto availableCodec = [](qsizetype index) -> QString + { + #if !QT_CONFIG(icu) + return QString::fromLatin1(encodingInterfaces[index].name); + #else + if (index == 0) // "Locale", not provided by icu + return QString::fromLatin1( + encodingInterfaces[QStringConverter::Encoding::System].name); + // this mirrors the setup we do to set a converters name + UErrorCode status = U_ZERO_ERROR; + auto icuName = ucnv_getAvailableName(int32_t(index - 1)); + const char *standardName = ucnv_getStandardName(icuName, "MIME", &status); + if (U_FAILURE(status) || !standardName) { + status = U_ZERO_ERROR; + standardName = ucnv_getStandardName(icuName, "IANA", &status); + } + if (!standardName) + standardName = icuName; + return QString::fromLatin1(standardName); + #endif + }; + + qsizetype codecCount = availableCodecCount(); + QStringList result; + result.reserve(codecCount); + for (qsizetype i = 0; i < codecCount; ++i) + result.push_back(availableCodec(i)); + return result; +} + + /*! Tries to determine the encoding of the HTML in \a data by looking at leading byte order marks or a charset specifier in the HTML meta tag and returns a QStringDecoder |