1
0
mirror of https://github.com/qTox/qTox.git synced 2024-03-22 14:00:36 +08:00

fix(file transfer widget): QPushButton allows image to overflow

Introduced in 857dfbcd4c

Regression was due to fact that QPushButton allows icon to overflow.
This patch does:
1. Scale and crop icon to fit into button.
2. Avoid upscaling small images.
3. Refactor FileTransferWidget::showPreview() to load image from file
   only once.

Closes #3042
This commit is contained in:
Vincas Dargis 2016-04-14 21:19:18 +03:00
parent 8fa40d5c4f
commit 32d588a499
3 changed files with 43 additions and 8 deletions

View File

@ -502,22 +502,24 @@ void FileTransferWidget::showPreview(const QString &filename)
if (previewExtensions.contains(QFileInfo(filename).suffix())) if (previewExtensions.contains(QFileInfo(filename).suffix()))
{ {
const int size = qMax(ui->previewButton->width(), ui->previewButton->height()); // Subtract to make border visible
const int size = qMax(ui->previewButton->width(), ui->previewButton->height()) - 4;
QPixmap pmap = QPixmap(filename).scaled(QSize(size, size), const QImage image = QImage(filename);
Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation); const QPixmap iconPixmap = scaleCropIntoSquare(QPixmap::fromImage(image), size);
ui->previewButton->setIcon(QIcon(pmap));
ui->previewButton->setIconSize(pmap.size()); ui->previewButton->setIcon(QIcon(iconPixmap));
ui->previewButton->setIconSize(iconPixmap.size());
ui->previewButton->show(); ui->previewButton->show();
// Show mouseover preview, but make sure it's not larger than 50% of the screen width/height // Show mouseover preview, but make sure it's not larger than 50% of the screen width/height
QRect desktopSize = QApplication::desktop()->screenGeometry(); const QRect desktopSize = QApplication::desktop()->screenGeometry();
QImage image = QImage(filename).scaled(0.5 * desktopSize.width(), const QImage previewImage = image.scaled(0.5 * desktopSize.width(),
0.5 * desktopSize.height(), 0.5 * desktopSize.height(),
Qt::KeepAspectRatio, Qt::SmoothTransformation); Qt::KeepAspectRatio, Qt::SmoothTransformation);
QByteArray imageData; QByteArray imageData;
QBuffer buffer(&imageData); QBuffer buffer(&imageData);
buffer.open(QIODevice::WriteOnly); buffer.open(QIODevice::WriteOnly);
image.save(&buffer, "PNG"); previewImage.save(&buffer, "PNG");
buffer.close(); buffer.close();
ui->previewButton->setToolTip("<img src=data:image/png;base64," + imageData.toBase64() + "/>"); ui->previewButton->setToolTip("<img src=data:image/png;base64," + imageData.toBase64() + "/>");
} }
@ -537,3 +539,30 @@ void FileTransferWidget::onPreviewButtonClicked()
{ {
handleButton(ui->previewButton); handleButton(ui->previewButton);
} }
QPixmap FileTransferWidget::scaleCropIntoSquare(const QPixmap &source, const int targetSize)
{
QPixmap result;
// Make sure smaller-than-icon images (at least one dimension is smaller) will not be upscaled
if (source.width() < targetSize || source.height() < targetSize)
{
result = source;
}
else
{
result = source.scaled(targetSize, targetSize,
Qt::KeepAspectRatioByExpanding,
Qt::SmoothTransformation);
}
// Then, image has to be cropped (if needed) so it will not overflow rectangle
// Only one dimension will be bigger after Qt::KeepAspectRatioByExpanding
if (result.width() > targetSize)
return result.copy((result.width() - targetSize) / 2, 0, targetSize, targetSize);
else if (result.height() > targetSize)
return result.copy(0, (result.height() - targetSize) / 2, targetSize, targetSize);
// Picture was rectangle in the first place, no cropping
return result;
}

View File

@ -72,6 +72,9 @@ private slots:
void onBottomButtonClicked(); void onBottomButtonClicked();
void onPreviewButtonClicked(); void onPreviewButtonClicked();
private:
static QPixmap scaleCropIntoSquare(const QPixmap &source, int targetSize);
private: private:
Ui::FileTransferWidget *ui; Ui::FileTransferWidget *ui;
ToxFile fileInfo; ToxFile fileInfo;

View File

@ -292,6 +292,9 @@
<property name="cursor"> <property name="cursor">
<cursorShape>PointingHandCursor</cursorShape> <cursorShape>PointingHandCursor</cursorShape>
</property> </property>
<property name="styleSheet">
<string notr="true">QPushButton{ border: 2px solid white }</string>
</property>
<property name="icon"> <property name="icon">
<iconset resource="../../../res.qrc"> <iconset resource="../../../res.qrc">
<normaloff>:/ui/fileTransferInstance/no.svg</normaloff>:/ui/fileTransferInstance/no.svg</iconset> <normaloff>:/ui/fileTransferInstance/no.svg</normaloff>:/ui/fileTransferInstance/no.svg</iconset>