diff --git a/linphone-app/CMakeLists.txt b/linphone-app/CMakeLists.txt
index 2519671f3..415dff304 100644
--- a/linphone-app/CMakeLists.txt
+++ b/linphone-app/CMakeLists.txt
@@ -99,6 +99,7 @@ set(SOURCES
src/app/paths/Paths.cpp
src/app/providers/AvatarProvider.cpp
src/app/providers/ImageProvider.cpp
+ src/app/providers/ExternalImageProvider.cpp
src/app/providers/ThumbnailProvider.cpp
src/app/translator/DefaultTranslator.cpp
src/components/assistant/AssistantModel.cpp
@@ -156,6 +157,7 @@ set(HEADERS
src/app/paths/Paths.hpp
src/app/providers/AvatarProvider.hpp
src/app/providers/ImageProvider.hpp
+ src/app/providers/ExternalImageProvider.hpp
src/app/providers/ThumbnailProvider.hpp
src/app/single-application/SingleApplication.hpp
src/app/translator/DefaultTranslator.hpp
diff --git a/linphone-app/src/app/App.cpp b/linphone-app/src/app/App.cpp
index 09d0457dc..823328631 100644
--- a/linphone-app/src/app/App.cpp
+++ b/linphone-app/src/app/App.cpp
@@ -41,6 +41,7 @@
#include "paths/Paths.hpp"
#include "providers/AvatarProvider.hpp"
#include "providers/ImageProvider.hpp"
+#include "providers/ExternalImageProvider.hpp"
#include "providers/ThumbnailProvider.hpp"
#include "translator/DefaultTranslator.hpp"
#include "utils/LinphoneUtils.hpp"
@@ -316,6 +317,7 @@ void App::initContentApp () {
// Provide avatars/thumbnails providers.
mEngine->addImageProvider(AvatarProvider::ProviderId, new AvatarProvider());
mEngine->addImageProvider(ImageProvider::ProviderId, new ImageProvider());
+ mEngine->addImageProvider(ExternalImageProvider::ProviderId, new ExternalImageProvider());
mEngine->addImageProvider(ThumbnailProvider::ProviderId, new ThumbnailProvider());
mEngine->rootContext()->setContextProperty("applicationUrl", APPLICATION_URL);
diff --git a/linphone-app/src/app/providers/ExternalImageProvider.cpp b/linphone-app/src/app/providers/ExternalImageProvider.cpp
new file mode 100644
index 000000000..76961e61c
--- /dev/null
+++ b/linphone-app/src/app/providers/ExternalImageProvider.cpp
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2010-2020 Belledonne Communications SARL.
+ *
+ * This file is part of linphone-desktop
+ * (see https://www.linphone.org).
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include "app/paths/Paths.hpp"
+#include "utils/Utils.hpp"
+
+#include "ExternalImageProvider.hpp"
+
+#include
+
+// =============================================================================
+
+const QString ExternalImageProvider::ProviderId = "external";
+
+ExternalImageProvider::ExternalImageProvider () : QQuickImageProvider(
+ QQmlImageProviderBase::Image,
+ QQmlImageProviderBase::ForceAsynchronousImageLoading
+) {
+}
+
+QImage ExternalImageProvider::requestImage (const QString &id, QSize *size, const QSize &) {
+ QImage image(id);
+ if(image.isNull()){// Try to determine format from headers instead of using suffix
+ QImageReader reader(id);
+ reader.setDecideFormatFromContent(true);
+ QByteArray format = reader.format();
+ if(!format.isEmpty())
+ image = QImage(id, format);
+ }
+ *size = image.size();
+ return image;
+}
diff --git a/linphone-app/src/app/providers/ExternalImageProvider.hpp b/linphone-app/src/app/providers/ExternalImageProvider.hpp
new file mode 100644
index 000000000..82b3964b2
--- /dev/null
+++ b/linphone-app/src/app/providers/ExternalImageProvider.hpp
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2010-2020 Belledonne Communications SARL.
+ *
+ * This file is part of linphone-desktop
+ * (see https://www.linphone.org).
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#ifndef EXTERNAL_IMAGE_PROVIDER_H_
+#define EXTERNAL_IMAGE_PROVIDER_H_
+
+#include
+
+// =============================================================================
+
+class ExternalImageProvider : public QQuickImageProvider {
+public:
+ ExternalImageProvider ();
+
+ QImage requestImage (const QString &id, QSize *size, const QSize &requestedSize) override;
+
+ static const QString ProviderId;
+};
+
+#endif // EXTERNAL_IMAGE_PROVIDER_H_
diff --git a/linphone-app/src/components/chat/ChatModel.cpp b/linphone-app/src/components/chat/ChatModel.cpp
index 811fce4ee..8c1c9ad73 100644
--- a/linphone-app/src/components/chat/ChatModel.cpp
+++ b/linphone-app/src/components/chat/ChatModel.cpp
@@ -28,6 +28,8 @@
#include
#include
#include
+#include
+#include
#include "app/App.hpp"
#include "app/paths/Paths.hpp"
@@ -129,45 +131,46 @@ static inline void createThumbnail (const shared_ptr &mes
std::list > contents = message->getContents();
if( contents.size() > 0)
{
- MessageAppData thumbnailData;
+ MessageAppData thumbnailData;
thumbnailData.m_path = Utils::coreStringToAppString(contents.front()->getFilePath());
- QImage image(thumbnailData.m_path);
- if (image.isNull())
- return;
-
- int rotation = 0;
- QExifImageHeader exifImageHeader;
- if (exifImageHeader.loadFromJpeg(thumbnailData.m_path))
- rotation = int(exifImageHeader.value(QExifImageHeader::ImageTag::Orientation).toShort());
-
- QImage thumbnail = image.scaled(
- ThumbnailImageFileWidth, ThumbnailImageFileHeight,
- Qt::KeepAspectRatio, Qt::SmoothTransformation
- );
-
- if (rotation != 0) {
- QTransform transform;
- if (rotation == 3 || rotation == 4)
- transform.rotate(180);
- else if (rotation == 5 || rotation == 6)
- transform.rotate(90);
- else if (rotation == 7 || rotation == 8)
- transform.rotate(-90);
-
- thumbnail = thumbnail.transformed(transform);
- if (rotation == 2 || rotation == 4 || rotation == 5 || rotation == 7)
- thumbnail = thumbnail.mirrored(true, false);
- }
-
- QString uuid = QUuid::createUuid().toString();
- thumbnailData.m_id = QStringLiteral("%1.jpg").arg(uuid.mid(1, uuid.length() - 2));
-
- if (!thumbnail.save(Utils::coreStringToAppString(Paths::getThumbnailsDirPath()) + thumbnailData.m_id , "jpg", 100)) {
- qWarning() << QStringLiteral("Unable to create thumbnail of: `%1`.").arg(thumbnailData.m_path);
- return;
- }
-
- message->setAppdata(Utils::appStringToCoreString(thumbnailData.toString()));
+ QImage image(thumbnailData.m_path);
+ if( image.isNull()){// Try to determine format from headers
+ QImageReader reader(thumbnailData.m_path);
+ reader.setDecideFormatFromContent(true);
+ QByteArray format = reader.format();
+ if(!format.isEmpty())
+ image = QImage(thumbnailData.m_path, format);
+ }
+ if (!image.isNull()){
+ int rotation = 0;
+ QExifImageHeader exifImageHeader;
+ if (exifImageHeader.loadFromJpeg(thumbnailData.m_path))
+ rotation = int(exifImageHeader.value(QExifImageHeader::ImageTag::Orientation).toShort());
+ QImage thumbnail = image.scaled(
+ ThumbnailImageFileWidth, ThumbnailImageFileHeight,
+ Qt::KeepAspectRatio, Qt::SmoothTransformation
+ );
+
+ if (rotation != 0) {
+ QTransform transform;
+ if (rotation == 3 || rotation == 4)
+ transform.rotate(180);
+ else if (rotation == 5 || rotation == 6)
+ transform.rotate(90);
+ else if (rotation == 7 || rotation == 8)
+ transform.rotate(-90);
+ thumbnail = thumbnail.transformed(transform);
+ if (rotation == 2 || rotation == 4 || rotation == 5 || rotation == 7)
+ thumbnail = thumbnail.mirrored(true, false);
+ }
+ QString uuid = QUuid::createUuid().toString();
+ thumbnailData.m_id = QStringLiteral("%1.jpg").arg(uuid.mid(1, uuid.length() - 2));
+
+ if (!thumbnail.save(Utils::coreStringToAppString(Paths::getThumbnailsDirPath()) + thumbnailData.m_id , "jpg", 100)) {
+ qWarning() << QStringLiteral("Unable to create thumbnail of: `%1`.").arg(thumbnailData.m_path);
+ }
+ }
+ message->setAppdata(Utils::appStringToCoreString(thumbnailData.toString()));
}
}
@@ -177,7 +180,7 @@ static inline void removeFileMessageThumbnail (const shared_ptr 0)
{
- QString thumbnailPath = Utils::coreStringToAppString(Paths::getThumbnailsDirPath()) + thumbnailFile.m_id;
+ QString thumbnailPath = Utils::coreStringToAppString(Paths::getThumbnailsDirPath()) + thumbnailFile.m_id;
if (!QFile::remove(thumbnailPath))
qWarning() << QStringLiteral("Unable to remove `%1`.").arg(thumbnailPath);
}
@@ -202,10 +205,11 @@ static inline void fillMessageEntry (QVariantMap &dest, const shared_ptr content = message->getFileTransferInformation();
if (content) {
dest["fileSize"] = quint64(content->getFileSize());
- dest["fileName"] = Utils::coreStringToAppString(content->getName());
- dest["wasDownloaded"] = ::fileWasDownloaded(message);
-
- fillThumbnailProperty(dest, message);
+ dest["fileName"] =Utils::coreStringToAppString(content->getName());
+ if (state==linphone::ChatMessage::State::Displayed)
+ createThumbnail(message);
+ fillThumbnailProperty(dest, message);
+ dest["wasDownloaded"] = ::fileWasDownloaded(message);
}
}
@@ -285,9 +289,7 @@ private:
if (state == linphone::ChatMessage::State::FileTransferDone && !message->isOutgoing()) {
createThumbnail(message);
fillThumbnailProperty((*it).first, message);
-
(*it).first["wasDownloaded"] = true;
-
App::getInstance()->getNotifier()->notifyReceivedFileMessage(message);
}
@@ -518,12 +520,10 @@ void ChatModel::sendFileMessage (const QString &path) {
content->setType(Utils::appStringToCoreString(mimeType[0]));
content->setSubtype(Utils::appStringToCoreString(mimeType[1]));
}
-
- content->setSize(size_t(fileSize));
- content->setName(Utils::appStringToCoreString(QFileInfo(file).fileName()));
-
+ content->setSize(size_t(fileSize));
+ content->setName(Utils::appStringToCoreString( QFileInfo(file).fileName()));
shared_ptr message = mChatRoom->createFileTransferMessage(content);
- message->getContents().front()->setFilePath(Utils::appStringToCoreString(path));// Sending only one File Path?
+ message->getContents().front()->setFilePath(Utils::appStringToCoreString(path));
message->addListener(mMessageHandlers);
createThumbnail(message);
@@ -570,9 +570,9 @@ void ChatModel::downloadFile (int id) {
message->getContents().front()->setFilePath(Utils::appStringToCoreString(safeFilePath));
- if( !message->isFileTransfer())
- QMessageBox::warning(nullptr, "Download File", "This file was already downloaded and is no more on the server. Your peer have to resend it if you want to get it");
- else
+ if( !message->isFileTransfer()){
+ QMessageBox::warning(nullptr, "Download File", "This file was already downloaded and is no more on the server. Your peer have to resend it if you want to get it");
+ }else
{
if (!message->downloadContent(message->getFileTransferInformation()))
qWarning() << QStringLiteral("Unable to download file of entry %1.").arg(id);
@@ -585,15 +585,14 @@ void ChatModel::openFile (int id, bool showDirectory) {
return;
shared_ptr message = static_pointer_cast(entry.second);
- if (!::fileWasDownloaded(message)) {
+ if (!entry.first["wasDownloaded"].toBool()) {
downloadFile(id);
- return;
+ }else{
+ QFileInfo info(getMessageAppData(message).m_path);
+ QDesktopServices::openUrl(
+ QUrl(QStringLiteral("file:///%1").arg(showDirectory ? info.absolutePath() : info.absoluteFilePath()))
+ );
}
-
- QFileInfo info(getMessageAppData(message).m_path);
- QDesktopServices::openUrl(
- QUrl(QStringLiteral("file:///%1").arg(showDirectory ? info.absolutePath() : info.absoluteFilePath()))
- );
}
bool ChatModel::fileWasDownloaded (int id) {
diff --git a/linphone-app/src/components/chat/ChatModel.hpp b/linphone-app/src/components/chat/ChatModel.hpp
index 60460f33e..2bee38c9a 100644
--- a/linphone-app/src/components/chat/ChatModel.hpp
+++ b/linphone-app/src/components/chat/ChatModel.hpp
@@ -61,9 +61,11 @@ public:
MessageStatusDisplayed = int(linphone::ChatMessage::State::Displayed),
MessageStatusFileTransferDone = int(linphone::ChatMessage::State::FileTransferDone),
MessageStatusFileTransferError = int(linphone::ChatMessage::State::FileTransferError),
+ MessageStatusFileTransferInProgress = int(linphone::ChatMessage::State::FileTransferInProgress),
MessageStatusIdle = int(linphone::ChatMessage::State::Idle),
MessageStatusInProgress = int(linphone::ChatMessage::State::InProgress),
MessageStatusNotDelivered = int(linphone::ChatMessage::State::NotDelivered)
+
};
Q_ENUM(MessageStatus);
diff --git a/linphone-app/src/components/notifier/Notifier.cpp b/linphone-app/src/components/notifier/Notifier.cpp
index ab7e9e76a..baaf29c3d 100644
--- a/linphone-app/src/components/notifier/Notifier.cpp
+++ b/linphone-app/src/components/notifier/Notifier.cpp
@@ -228,7 +228,7 @@ void Notifier::deleteNotification (QVariant notification) {
// -----------------------------------------------------------------------------
void Notifier::notifyReceivedMessage (const shared_ptr &message) {
- CREATE_NOTIFICATION(Notifier::ReceivedMessage);
+ CREATE_NOTIFICATION(Notifier::ReceivedMessage)
QVariantMap map;
map["message"] = message->getFileTransferInformation()
@@ -240,21 +240,21 @@ void Notifier::notifyReceivedMessage (const shared_ptr &m
map["localAddress"] = Utils::coreStringToAppString(chatRoom->getLocalAddress()->asStringUriOnly());
map["window"].setValue(App::getInstance()->getMainWindow());
- SHOW_NOTIFICATION(map);
+ SHOW_NOTIFICATION(map)
}
void Notifier::notifyReceivedFileMessage (const shared_ptr &message) {
- CREATE_NOTIFICATION(Notifier::ReceivedFileMessage);
+ CREATE_NOTIFICATION(Notifier::ReceivedFileMessage)
QVariantMap map;
- map["fileUri"] = Utils::coreStringToAppString(message->getFileTransferFilepath());
- map["fileSize"] = quint64(message->getFileTransferInformation()->getSize());
+ map["fileUri"] = Utils::coreStringToAppString(message->getFileTransferInformation()->getFilePath());
+ map["fileSize"] = quint64(message->getFileTransferInformation()->getSize() +message->getFileTransferInformation()->getFileSize());
- SHOW_NOTIFICATION(map);
+ SHOW_NOTIFICATION(map)
}
void Notifier::notifyReceivedCall (const shared_ptr &call) {
- CREATE_NOTIFICATION(Notifier::ReceivedCall);
+ CREATE_NOTIFICATION(Notifier::ReceivedCall)
CallModel *callModel = &call->getData("call-model");
@@ -266,35 +266,35 @@ void Notifier::notifyReceivedCall (const shared_ptr &call) {
QVariantMap map;
map["call"].setValue(callModel);
- SHOW_NOTIFICATION(map);
+ SHOW_NOTIFICATION(map)
}
void Notifier::notifyNewVersionAvailable (const QString &version, const QString &url) {
- CREATE_NOTIFICATION(Notifier::NewVersionAvailable);
+ CREATE_NOTIFICATION(Notifier::NewVersionAvailable)
QVariantMap map;
map["message"] = tr("newVersionAvailable").arg(version);
map["url"] = url;
- SHOW_NOTIFICATION(map);
+ SHOW_NOTIFICATION(map)
}
void Notifier::notifySnapshotWasTaken (const QString &filePath) {
- CREATE_NOTIFICATION(Notifier::SnapshotWasTaken);
+ CREATE_NOTIFICATION(Notifier::SnapshotWasTaken)
QVariantMap map;
map["filePath"] = filePath;
- SHOW_NOTIFICATION(map);
+ SHOW_NOTIFICATION(map)
}
void Notifier::notifyRecordingCompleted (const QString &filePath) {
- CREATE_NOTIFICATION(Notifier::RecordingCompleted);
+ CREATE_NOTIFICATION(Notifier::RecordingCompleted)
QVariantMap map;
map["filePath"] = filePath;
- SHOW_NOTIFICATION(map);
+ SHOW_NOTIFICATION(map)
}
#undef SHOW_NOTIFICATION
diff --git a/linphone-app/ui/modules/Linphone/Chat/FileMessage.qml b/linphone-app/ui/modules/Linphone/Chat/FileMessage.qml
index 13d2f6420..57460f086 100644
--- a/linphone-app/ui/modules/Linphone/Chat/FileMessage.qml
+++ b/linphone-app/ui/modules/Linphone/Chat/FileMessage.qml
@@ -200,7 +200,7 @@ Row {
to: $chatEntry.fileSize
value: $chatEntry.fileOffset || 0
- visible: $chatEntry.status === ChatModel.MessageStatusInProgress
+ visible: $chatEntry.status === ChatModel.MessageStatusInProgress || $chatEntry.status === ChatModel.MessageStatusFileTransferInProgress
background: Rectangle {
color: ChatStyle.entry.message.file.status.bar.background.color
@@ -322,7 +322,7 @@ Row {
sourceComponent: $chatEntry.isOutgoing
? (
- $chatEntry.status === ChatModel.MessageStatusInProgress
+ $chatEntry.status === ChatModel.MessageStatusInProgress || $chatEntry.status === ChatModel.MessageStatusFileTransferInProgress
? indicator
: icon
) : undefined
diff --git a/linphone-app/ui/modules/Linphone/Chat/OutgoingMessage.qml b/linphone-app/ui/modules/Linphone/Chat/OutgoingMessage.qml
index 9318c3171..ebdf19302 100644
--- a/linphone-app/ui/modules/Linphone/Chat/OutgoingMessage.qml
+++ b/linphone-app/ui/modules/Linphone/Chat/OutgoingMessage.qml
@@ -80,7 +80,7 @@ Item {
height: ChatStyle.entry.lineHeight
width: ChatStyle.entry.message.outgoing.areaSize
- sourceComponent: $chatEntry.status === ChatModel.MessageStatusInProgress
+ sourceComponent: $chatEntry.status === ChatModel.MessageStatusInProgress || $chatEntry.status === ChatModel.MessageStatusFileTransferInProgress
? indicator
: icon
}
diff --git a/linphone-app/ui/modules/Linphone/Notifications/NotificationReceivedFileMessage.qml b/linphone-app/ui/modules/Linphone/Notifications/NotificationReceivedFileMessage.qml
index 2ca3cfdfd..56dbe2af0 100644
--- a/linphone-app/ui/modules/Linphone/Notifications/NotificationReceivedFileMessage.qml
+++ b/linphone-app/ui/modules/Linphone/Notifications/NotificationReceivedFileMessage.qml
@@ -39,6 +39,15 @@ Notification {
elide: Text.ElideRight
font.pointSize: NotificationReceivedFileMessageStyle.fileName.pointSize
text: Utils.basename(notification.fileUri)
+ visible:!image.visible
+ }
+ Image{
+ id:image
+ Layout.fillHeight: true
+ Layout.fillWidth: true
+ fillMode: Image.PreserveAspectFit
+ source: "image://external/"+notification.fileUri
+ visible: image.status == Image.Ready
}
Text {