|
|
|
@ -39,6 +39,7 @@
@@ -39,6 +39,7 @@
|
|
|
|
|
#include <QPainter> |
|
|
|
|
#include <QVariantAnimation> |
|
|
|
|
|
|
|
|
|
#include <cassert> |
|
|
|
|
#include <math.h> |
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -148,10 +149,11 @@ void FileTransferWidget::autoAcceptTransfer(const QString& path)
@@ -148,10 +149,11 @@ void FileTransferWidget::autoAcceptTransfer(const QString& path)
|
|
|
|
|
|
|
|
|
|
// Do not automatically accept the file-transfer if the path is not writable.
|
|
|
|
|
// The user can still accept it manually.
|
|
|
|
|
if (tryRemoveFile(filepath)) |
|
|
|
|
if (tryRemoveFile(filepath)) { |
|
|
|
|
Core::getInstance()->acceptFileRecvRequest(fileInfo.friendId, fileInfo.fileNum, filepath); |
|
|
|
|
else |
|
|
|
|
} else { |
|
|
|
|
qWarning() << "Cannot write to " << filepath; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
bool FileTransferWidget::isActive() const |
|
|
|
@ -161,8 +163,9 @@ bool FileTransferWidget::isActive() const
@@ -161,8 +163,9 @@ bool FileTransferWidget::isActive() const
|
|
|
|
|
|
|
|
|
|
void FileTransferWidget::acceptTransfer(const QString& filepath) |
|
|
|
|
{ |
|
|
|
|
if (filepath.isEmpty()) |
|
|
|
|
if (filepath.isEmpty()) { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// test if writable
|
|
|
|
|
if (!tryRemoveFile(filepath)) { |
|
|
|
@ -290,17 +293,19 @@ void FileTransferWidget::onFileTransferFinished(ToxFile file)
@@ -290,17 +293,19 @@ void FileTransferWidget::onFileTransferFinished(ToxFile file)
|
|
|
|
|
|
|
|
|
|
void FileTransferWidget::fileTransferRemotePausedUnpaused(ToxFile file, bool paused) |
|
|
|
|
{ |
|
|
|
|
if (paused) |
|
|
|
|
if (paused) { |
|
|
|
|
onFileTransferPaused(file); |
|
|
|
|
else |
|
|
|
|
} else { |
|
|
|
|
onFileTransferResumed(file); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void FileTransferWidget::fileTransferBrokenUnbroken(ToxFile file, bool broken) |
|
|
|
|
{ |
|
|
|
|
// TODO: Handle broken transfer differently once we have resuming code
|
|
|
|
|
if (broken) |
|
|
|
|
if (broken) { |
|
|
|
|
onFileTransferCancelled(file); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
QString FileTransferWidget::getHumanReadableSize(qint64 size) |
|
|
|
@ -308,16 +313,18 @@ QString FileTransferWidget::getHumanReadableSize(qint64 size)
@@ -308,16 +313,18 @@ QString FileTransferWidget::getHumanReadableSize(qint64 size)
|
|
|
|
|
static const char* suffix[] = {"B", "kiB", "MiB", "GiB", "TiB"}; |
|
|
|
|
int exp = 0; |
|
|
|
|
|
|
|
|
|
if (size > 0) |
|
|
|
|
if (size > 0) { |
|
|
|
|
exp = std::min((int)(log(size) / log(1024)), (int)(sizeof(suffix) / sizeof(suffix[0]) - 1)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return QString().setNum(size / pow(1024, exp), 'f', exp > 1 ? 2 : 0).append(suffix[exp]); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void FileTransferWidget::updateWidgetColor(ToxFile const& file) |
|
|
|
|
{ |
|
|
|
|
if (lastStatus == file.status) |
|
|
|
|
if (lastStatus == file.status) { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
switch (file.status) { |
|
|
|
|
case ToxFile::INITIALIZING: |
|
|
|
@ -332,13 +339,16 @@ void FileTransferWidget::updateWidgetColor(ToxFile const& file)
@@ -332,13 +339,16 @@ void FileTransferWidget::updateWidgetColor(ToxFile const& file)
|
|
|
|
|
case ToxFile::FINISHED: |
|
|
|
|
setBackgroundColor(Style::getColor(Style::Green), true); |
|
|
|
|
break; |
|
|
|
|
default: |
|
|
|
|
assert(false); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void FileTransferWidget::updateWidgetText(ToxFile const& file) |
|
|
|
|
{ |
|
|
|
|
if (lastStatus == file.status) |
|
|
|
|
if (lastStatus == file.status) { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
switch (file.status) { |
|
|
|
|
case ToxFile::INITIALIZING: |
|
|
|
@ -361,29 +371,33 @@ void FileTransferWidget::updateWidgetText(ToxFile const& file)
@@ -361,29 +371,33 @@ void FileTransferWidget::updateWidgetText(ToxFile const& file)
|
|
|
|
|
break; |
|
|
|
|
case ToxFile::FINISHED: |
|
|
|
|
break; |
|
|
|
|
default: |
|
|
|
|
assert(false); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void FileTransferWidget::updatePreview(ToxFile const& file) |
|
|
|
|
{ |
|
|
|
|
if (lastStatus == file.status) |
|
|
|
|
if (lastStatus == file.status) { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
switch (file.status) { |
|
|
|
|
case ToxFile::INITIALIZING: |
|
|
|
|
case ToxFile::PAUSED: |
|
|
|
|
case ToxFile::TRANSMITTING: |
|
|
|
|
case ToxFile::BROKEN: |
|
|
|
|
case ToxFile::CANCELED: |
|
|
|
|
if (file.direction == ToxFile::SENDING) { |
|
|
|
|
showPreview(file.filePath); |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
case ToxFile::FINISHED: |
|
|
|
|
case ToxFile::INITIALIZING: |
|
|
|
|
case ToxFile::PAUSED: |
|
|
|
|
case ToxFile::TRANSMITTING: |
|
|
|
|
case ToxFile::BROKEN: |
|
|
|
|
case ToxFile::CANCELED: |
|
|
|
|
if (file.direction == ToxFile::SENDING) { |
|
|
|
|
showPreview(file.filePath); |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
case ToxFile::FINISHED: |
|
|
|
|
showPreview(file.filePath); |
|
|
|
|
break; |
|
|
|
|
default: |
|
|
|
|
assert(false); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void FileTransferWidget::updateFileProgress(ToxFile const& file) |
|
|
|
@ -395,8 +409,9 @@ void FileTransferWidget::updateFileProgress(ToxFile const& file)
@@ -395,8 +409,9 @@ void FileTransferWidget::updateFileProgress(ToxFile const& file)
|
|
|
|
|
fileProgress.resetSpeed(); |
|
|
|
|
break; |
|
|
|
|
case ToxFile::TRANSMITTING: { |
|
|
|
|
if (!fileProgress.needsUpdate()) |
|
|
|
|
if (!fileProgress.needsUpdate()) { |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
fileProgress.addSample(file); |
|
|
|
|
auto speed = fileProgress.getSpeed(); |
|
|
|
@ -426,13 +441,16 @@ void FileTransferWidget::updateFileProgress(ToxFile const& file)
@@ -426,13 +441,16 @@ void FileTransferWidget::updateFileProgress(ToxFile const& file)
|
|
|
|
|
ui->etaLabel->hide(); |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
default: |
|
|
|
|
assert(false); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void FileTransferWidget::updateSignals(ToxFile const& file) |
|
|
|
|
{ |
|
|
|
|
if (lastStatus == file.status) |
|
|
|
|
if (lastStatus == file.status) { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
switch (file.status) { |
|
|
|
|
case ToxFile::CANCELED: |
|
|
|
@ -445,13 +463,16 @@ void FileTransferWidget::updateSignals(ToxFile const& file)
@@ -445,13 +463,16 @@ void FileTransferWidget::updateSignals(ToxFile const& file)
|
|
|
|
|
case ToxFile::PAUSED: |
|
|
|
|
case ToxFile::TRANSMITTING: |
|
|
|
|
break; |
|
|
|
|
default: |
|
|
|
|
assert(false); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void FileTransferWidget::setupButtons(ToxFile const& file) |
|
|
|
|
{ |
|
|
|
|
if (lastStatus == file.status) |
|
|
|
|
if (lastStatus == file.status) { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
switch (file.status) { |
|
|
|
|
case ToxFile::TRANSMITTING: |
|
|
|
@ -510,27 +531,30 @@ void FileTransferWidget::setupButtons(ToxFile const& file)
@@ -510,27 +531,30 @@ void FileTransferWidget::setupButtons(ToxFile const& file)
|
|
|
|
|
ui->rightButton->show(); |
|
|
|
|
|
|
|
|
|
break; |
|
|
|
|
default: |
|
|
|
|
assert(false); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void FileTransferWidget::handleButton(QPushButton* btn) |
|
|
|
|
{ |
|
|
|
|
if (fileInfo.direction == ToxFile::SENDING) { |
|
|
|
|
if (btn->objectName() == "cancel") |
|
|
|
|
if (btn->objectName() == "cancel") { |
|
|
|
|
Core::getInstance()->cancelFileSend(fileInfo.friendId, fileInfo.fileNum); |
|
|
|
|
else if (btn->objectName() == "pause") |
|
|
|
|
} else if (btn->objectName() == "pause") { |
|
|
|
|
Core::getInstance()->pauseResumeFileSend(fileInfo.friendId, fileInfo.fileNum); |
|
|
|
|
else if (btn->objectName() == "resume") |
|
|
|
|
} else if (btn->objectName() == "resume") { |
|
|
|
|
Core::getInstance()->pauseResumeFileSend(fileInfo.friendId, fileInfo.fileNum); |
|
|
|
|
} |
|
|
|
|
} else // receiving or paused
|
|
|
|
|
{ |
|
|
|
|
if (btn->objectName() == "cancel") |
|
|
|
|
if (btn->objectName() == "cancel") { |
|
|
|
|
Core::getInstance()->cancelFileRecv(fileInfo.friendId, fileInfo.fileNum); |
|
|
|
|
else if (btn->objectName() == "pause") |
|
|
|
|
} else if (btn->objectName() == "pause") { |
|
|
|
|
Core::getInstance()->pauseResumeFileRecv(fileInfo.friendId, fileInfo.fileNum); |
|
|
|
|
else if (btn->objectName() == "resume") |
|
|
|
|
} else if (btn->objectName() == "resume") { |
|
|
|
|
Core::getInstance()->pauseResumeFileRecv(fileInfo.friendId, fileInfo.fileNum); |
|
|
|
|
else if (btn->objectName() == "accept") { |
|
|
|
|
} else if (btn->objectName() == "accept") { |
|
|
|
|
QString path = |
|
|
|
|
QFileDialog::getSaveFileName(Q_NULLPTR, |
|
|
|
|
tr("Save a file", "Title of the file saving dialog"), |
|
|
|
@ -575,7 +599,8 @@ void FileTransferWidget::showPreview(const QString& filename)
@@ -575,7 +599,8 @@ void FileTransferWidget::showPreview(const QString& filename)
|
|
|
|
|
ui->previewButton->setIcon(QIcon(iconPixmap)); |
|
|
|
|
ui->previewButton->setIconSize(iconPixmap.size()); |
|
|
|
|
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
|
|
|
|
|
const QRect desktopSize = QApplication::desktop()->screenGeometry(); |
|
|
|
|
const int maxPreviewWidth{desktopSize.width() / 2}; |
|
|
|
|
const int maxPreviewHeight{desktopSize.height() / 2}; |
|
|
|
@ -616,7 +641,8 @@ QPixmap FileTransferWidget::scaleCropIntoSquare(const QPixmap& source, const int
@@ -616,7 +641,8 @@ QPixmap FileTransferWidget::scaleCropIntoSquare(const QPixmap& source, const int
|
|
|
|
|
{ |
|
|
|
|
QPixmap result; |
|
|
|
|
|
|
|
|
|
// Make sure smaller-than-icon images (at least one dimension is smaller) will not be upscaled
|
|
|
|
|
// 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 { |
|
|
|
@ -626,10 +652,11 @@ QPixmap FileTransferWidget::scaleCropIntoSquare(const QPixmap& source, const int
@@ -626,10 +652,11 @@ QPixmap FileTransferWidget::scaleCropIntoSquare(const QPixmap& source, const int
|
|
|
|
|
|
|
|
|
|
// 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) |
|
|
|
|
if (result.width() > targetSize) { |
|
|
|
|
return result.copy((result.width() - targetSize) / 2, 0, targetSize, targetSize); |
|
|
|
|
else if (result.height() > 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; |
|
|
|
@ -639,8 +666,9 @@ int FileTransferWidget::getExifOrientation(const char* data, const int size)
@@ -639,8 +666,9 @@ int FileTransferWidget::getExifOrientation(const char* data, const int size)
|
|
|
|
|
{ |
|
|
|
|
ExifData* exifData = exif_data_new_from_data(reinterpret_cast<const unsigned char*>(data), size); |
|
|
|
|
|
|
|
|
|
if (!exifData) |
|
|
|
|
if (!exifData) { |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int orientation = 0; |
|
|
|
|
const ExifByteOrder byteOrder = exif_data_get_byte_order(exifData); |
|
|
|
@ -689,8 +717,9 @@ void FileTransferWidget::applyTransformation(const int orientation, QImage& imag
@@ -689,8 +717,9 @@ void FileTransferWidget::applyTransformation(const int orientation, QImage& imag
|
|
|
|
|
|
|
|
|
|
void FileTransferWidget::updateWidget(ToxFile const& file) |
|
|
|
|
{ |
|
|
|
|
if (fileInfo != file) |
|
|
|
|
if (fileInfo != file) { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
fileInfo = file; |
|
|
|
|
|
|
|
|
@ -709,9 +738,10 @@ void FileTransferWidget::updateWidget(ToxFile const& file)
@@ -709,9 +738,10 @@ void FileTransferWidget::updateWidget(ToxFile const& file)
|
|
|
|
|
// trigger repaint
|
|
|
|
|
switch (file.status) { |
|
|
|
|
case ToxFile::TRANSMITTING: |
|
|
|
|
if (!bTransmitNeedsUpdate) |
|
|
|
|
if (!bTransmitNeedsUpdate) { |
|
|
|
|
break; |
|
|
|
|
// fallthrough
|
|
|
|
|
} |
|
|
|
|
// fallthrough
|
|
|
|
|
default: |
|
|
|
|
update(); |
|
|
|
|
} |
|
|
|
|