qt: Handle encoding for diagnostics

* lang/qt/src/threadedjobmixin.cpp (fromEncoding)
(stringFromGpgOutput): New helpers.
(markupDiagnostics): Use it.

--
The Problem is that on my western windows system GnuPG
gets CP 437 as GetConsoleOutputCP and prints in that codepage.
In a W32 GUI Application we get 0 as GetConsoleOutputCP and 1252
with GetACP.

The only thing that seemed to somehow match was GetOEMCP but
that might just be luck and it might still be broken in
other windows languages.

This code is also used in Kleopatra so it might make sense
to make it public once it is demonstrated that it works on
most systems.
This commit is contained in:
Andre Heinecke 2018-07-18 11:27:46 +02:00
parent 1686e07e77
commit 16462c54b3
No known key found for this signature in database
GPG Key ID: 2978E9D40CBABA5C

View File

@ -53,6 +53,58 @@
using namespace QGpgME; using namespace QGpgME;
using namespace GpgME; using namespace GpgME;
#ifdef Q_OS_WIN
#include <windows.h>
static QString fromEncoding (unsigned int src_encoding, const char *data)
{
int n = MultiByteToWideChar(src_encoding, 0, data, -1, NULL, 0);
if (n < 0) {
return QString();
}
wchar_t *result = (wchar_t *) malloc ((n+1) * sizeof *result);
n = MultiByteToWideChar(src_encoding, 0, data, -1, result, n);
if (n < 0) {
free(result);
return QString();
}
const auto ret = QString::fromWCharArray(result, n);
free(result);
return ret;
}
#endif
static QString stringFromGpgOutput(const QByteArray &ba)
{
#ifdef Q_OS_WIN
/* Qt on Windows uses GetACP while GnuPG prefers
* GetConsoleOutputCP.
*
* As we are not a console application GetConsoleOutputCP
* usually returns 0.
* From experience the closest thing that let's us guess
* what GetConsoleOutputCP returns for a console application
* it appears to be the OEMCP.
*/
unsigned int cpno = GetConsoleOutputCP ();
if (!cpno) {
cpno = GetOEMCP();
}
if (!cpno) {
cpno = GetACP();
}
if (!cpno) {
return QString();
}
return fromEncoding(cpno, ba.constData());
#else
return QString::fromLocal8Bit(ba);
#endif
}
static QString markupDiagnostics(const QString &data) static QString markupDiagnostics(const QString &data)
{ {
// First ensure that we don't have html in the diag. // First ensure that we don't have html in the diag.
@ -76,7 +128,7 @@ QString _detail::audit_log_as_html(Context *ctx, GpgME::Error &err)
return QString::fromLocal8Bit(err.asString()); return QString::fromLocal8Bit(err.asString());
} }
const QByteArray ba = dp.data(); const QByteArray ba = dp.data();
return markupDiagnostics(QString::fromUtf8(ba.data(), ba.size())); return markupDiagnostics(stringFromGpgOutput(ba));
} }
if (ctx->protocol() == CMS) { if (ctx->protocol() == CMS) {