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>
This commit is contained in:
parent
bc9ad7db6b
commit
90226018a9
@ -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
|
||||
|
@ -13,6 +13,7 @@
|
||||
|
||||
#include <QtCore/qglobal.h> // QT_{BEGIN,END}_NAMESPACE
|
||||
#include <QtCore/qflags.h> // Q_DECLARE_FLAGS
|
||||
#include <QtCore/qcontainerfwd.h>
|
||||
|
||||
#include <cstring>
|
||||
|
||||
@ -159,6 +160,8 @@ public:
|
||||
encodingForData(QByteArrayView data, char16_t expectedFirstCharacter = 0) noexcept;
|
||||
Q_CORE_EXPORT static std::optional<Encoding> encodingForHtml(QByteArrayView data);
|
||||
|
||||
Q_CORE_EXPORT static QStringList availableCodecs();
|
||||
|
||||
protected:
|
||||
const Interface *iface;
|
||||
State state;
|
||||
|
@ -178,6 +178,8 @@ private slots:
|
||||
|
||||
void encodingForHtml_data();
|
||||
void encodingForHtml();
|
||||
|
||||
void availableCodesAreAvailable();
|
||||
};
|
||||
|
||||
void tst_QStringConverter::constructByName()
|
||||
@ -2426,6 +2428,13 @@ void tst_QStringConverter::encodingForHtml()
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QStringConverter::availableCodesAreAvailable()
|
||||
{
|
||||
auto codecs = QStringConverter::availableCodecs();
|
||||
for (const auto &codecName: codecs)
|
||||
QVERIFY(QStringEncoder(codecName.toLatin1()).isValid());
|
||||
}
|
||||
|
||||
class LoadAndConvert: public QRunnable
|
||||
{
|
||||
public:
|
||||
|
Loading…
Reference in New Issue
Block a user