Merge pull request #4632: FEAT(client): Easier pasting of images

Currently pasting or dragging and dropping images in the Mumble chat is
difficult because:

1. They are rejected because they exceed the allowed size. As a user I
    would not expect it to transmitted losslessly but I would hope that the
    client compresses it to a size the server allows.
2. Images are rejected because the server does not allow html. When
    inserting an image via drag and drop you aren't notified what went
    wrong.
This commit is contained in:
Robert Adam 2020-12-23 08:26:47 +01:00 committed by GitHub
commit 38974e7664
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 46 additions and 44 deletions

View File

@ -180,43 +180,48 @@ void ChatbarTextEdit::insertFromMimeData(const QMimeData *source) {
}
bool ChatbarTextEdit::sendImagesFromMimeData(const QMimeData *source) {
if (source->hasImage()) {
// Process the image pasted onto the chatbar.
if (g.bAllowHTML) {
if (g.bAllowHTML) {
if (source->hasImage()) {
// Process the image pasted onto the chatbar.
QImage image = qvariant_cast< QImage >(source->imageData());
QString imgHtml = QLatin1String("<br />") + Log::imageToImg(image);
if ((g.uiImageLength == 0) || static_cast< unsigned int >(imgHtml.length()) < g.uiImageLength) {
emit pastedImage(imgHtml);
if (emitPastedImage(image)) {
return true;
} else {
g.l->log(Log::Information, tr("Unable to send image: too large."));
return false;
}
}
} else if (source->hasUrls()) {
// Process the files dropped onto the chatbar. URLs here should be understood as the URIs of files.
QList< QUrl > urlList = source->urls();
int count = 0;
for (int i = 0; i < urlList.size(); ++i) {
QString path = urlList[i].toLocalFile();
QImage image(path);
} else if (source->hasUrls()) {
// Process the files dropped onto the chatbar. URLs here should be understood as the URIs of files.
QList< QUrl > urlList = source->urls();
if (image.isNull())
continue;
int count = 0;
for (int i = 0; i < urlList.size(); ++i) {
QString path = urlList[i].toLocalFile();
QImage image(path);
QString imgHtml = QLatin1String("<br />") + Log::imageToImg(image);
if (static_cast< unsigned int >(imgHtml.length()) < g.uiImageLength) {
emit pastedImage(imgHtml);
++count;
} else {
g.l->log(Log::Information, tr("Unable to send image %1: too large.").arg(path));
if (image.isNull())
continue;
if (emitPastedImage(image)) {
++count;
} else {
g.l->log(Log::Information, tr("Unable to send image %1: too large.").arg(path));
}
}
}
return (count > 0);
return (count > 0);
}
}
g.l->log(Log::Information, tr("This server does not allow sending images."));
return false;
}
bool ChatbarTextEdit::emitPastedImage(QImage image) {
QString processedImage = Log::imageToImg(image, g.uiImageLength);
if (processedImage.length() > 0) {
QString imgHtml = QLatin1String("<br />") + processedImage;
emit pastedImage(imgHtml);
return true;
}
return false;
}

View File

@ -53,6 +53,7 @@ protected:
void resizeEvent(QResizeEvent *e) Q_DECL_OVERRIDE;
void insertFromMimeData(const QMimeData *source) Q_DECL_OVERRIDE;
bool sendImagesFromMimeData(const QMimeData *source);
bool emitPastedImage(QImage image);
public:
void setDefaultText(const QString &, bool = false);

View File

@ -522,38 +522,30 @@ QString Log::imageToImg(const QByteArray &format, const QByteArray &image) {
return QString::fromLatin1("<img src=\"data:image/%1;base64,%2\" />").arg(fmt).arg(QLatin1String(encoded));
}
QString Log::imageToImg(QImage img) {
QString Log::imageToImg(QImage img, int maxSize) {
if ((img.width() > 480) || (img.height() > 270)) {
img = img.scaled(480, 270, Qt::KeepAspectRatio, Qt::SmoothTransformation);
}
int quality = 100;
QByteArray format = "PNG";
QByteArray format = "JPEG";
QByteArray qba;
{
QBuffer qb(&qba);
qb.open(QIODevice::WriteOnly);
QImageWriter imgwrite(&qb, format);
imgwrite.write(img);
}
while ((qba.length() >= 65536) && (quality > 0)) {
QString result;
while (quality > 0) {
qba.clear();
QBuffer qb(&qba);
qb.open(QIODevice::WriteOnly);
format = "JPEG";
QImageWriter imgwrite(&qb, format);
imgwrite.setQuality(quality);
imgwrite.write(img);
result = imageToImg(format, qba);
if (result.length() < maxSize || maxSize == 0) {
return result;
}
quality -= 10;
}
if (qba.length() < 65536) {
return imageToImg(format, qba);
}
return QString();
}

View File

@ -125,7 +125,7 @@ public:
void clearIgnore();
static QString validHtml(const QString &html, QTextCursor *tc = nullptr);
static QString imageToImg(const QByteArray &format, const QByteArray &image);
static QString imageToImg(QImage img);
static QString imageToImg(QImage img, int maxSize = 0);
static QString msgColor(const QString &text, LogColorType t);
static QString formatClientUser(ClientUser *cu, LogColorType t, const QString &displayName = QString());
static QString formatChannel(::Channel *c);

View File

@ -2694,6 +2694,10 @@ Are you sure you wish to replace your certificate?
<source>Unable to send image %1: too large.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>This server does not allow sending images.</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>ClientUser</name>