diff --git a/tests/assets/languages/en.ts b/tests/assets/languages/en.ts
index 6755d2916..308fad2f1 100644
--- a/tests/assets/languages/en.ts
+++ b/tests/assets/languages/en.ts
@@ -311,6 +311,13 @@ Server url not configured.
Missed outgoing call
+
+ FileMessage
+
+ downloadFileTitle
+
+
+
Home
diff --git a/tests/assets/languages/fr.ts b/tests/assets/languages/fr.ts
index 71f21dcf9..dcef4df81 100644
--- a/tests/assets/languages/fr.ts
+++ b/tests/assets/languages/fr.ts
@@ -299,6 +299,13 @@ Url du serveur non configurée.
Appel sortant sans réponse
+
+ FileMessage
+
+ downloadFileTitle
+
+
+
Home
diff --git a/tests/src/components/chat/ChatModel.cpp b/tests/src/components/chat/ChatModel.cpp
index bf8ce2e4e..564d267fb 100644
--- a/tests/src/components/chat/ChatModel.cpp
+++ b/tests/src/components/chat/ChatModel.cpp
@@ -1,6 +1,7 @@
#include
#include
+#include
#include
#include
#include
@@ -22,10 +23,36 @@ using namespace std;
// =============================================================================
inline void fillThumbnailProperty (QVariantMap &dest, const shared_ptr &message) {
- string data = message->getAppdata();
- if (!data.empty())
+ string file_id = message->getAppdata();
+ if (!file_id.empty() && !dest.contains("thumbnail"))
dest["thumbnail"] = QStringLiteral("image://%1/%2")
- .arg(ThumbnailProvider::PROVIDER_ID).arg(::Utils::linphoneStringToQString(data));
+ .arg(ThumbnailProvider::PROVIDER_ID).arg(::Utils::linphoneStringToQString(file_id));
+}
+
+inline void createThumbnail (const shared_ptr &message) {
+ if (!message->getAppdata().empty())
+ return;
+
+ QString thumbnail_path = ::Utils::linphoneStringToQString(message->getFileTransferFilepath());
+
+ QImage image(thumbnail_path);
+ if (image.isNull())
+ return;
+
+ QImage thumbnail = image.scaled(
+ THUMBNAIL_IMAGE_FILE_WIDTH, THUMBNAIL_IMAGE_FILE_HEIGHT,
+ Qt::KeepAspectRatio, Qt::SmoothTransformation
+ );
+
+ QString uuid = QUuid::createUuid().toString();
+ QString file_id = QStringLiteral("%1.jpg").arg(uuid.mid(1, uuid.length() - 2));
+
+ if (!thumbnail.save(::Utils::linphoneStringToQString(Paths::getThumbnailsDirPath()) + file_id, "jpg", 100)) {
+ qWarning() << QStringLiteral("Unable to create thumbnail of: `%1`.").arg(thumbnail_path);
+ return;
+ }
+
+ message->setAppdata(::Utils::qStringToLinphoneString(file_id));
}
inline void removeFileMessageThumbnail (const shared_ptr &message) {
@@ -112,24 +139,8 @@ private:
if (state == linphone::ChatMessageStateFileTransferError)
state = linphone::ChatMessageStateNotDelivered;
else if (state == linphone::ChatMessageStateFileTransferDone) {
- QString thumbnail_path = ::Utils::linphoneStringToQString(message->getFileTransferFilepath());
-
- QImage image(thumbnail_path);
- if (!image.isNull()) {
- QImage thumbnail = image.scaled(
- THUMBNAIL_IMAGE_FILE_WIDTH, THUMBNAIL_IMAGE_FILE_HEIGHT,
- Qt::KeepAspectRatio, Qt::SmoothTransformation
- );
-
- QString uuid = QUuid::createUuid().toString();
- QString file_id = QStringLiteral("%1.jpg").arg(uuid.mid(1, uuid.length() - 2));
-
- if (!thumbnail.save(::Utils::linphoneStringToQString(Paths::getThumbnailsDirPath()) + file_id, "jpg", 100)) {
- qWarning() << QStringLiteral("Unable to create thumbnail of: `%1`.").arg(thumbnail_path);
- return;
- }
-
- message->setAppdata(::Utils::qStringToLinphoneString(file_id));
+ if (!message->isOutgoing()) {
+ createThumbnail(message);
fillThumbnailProperty((*it).first, message);
}
@@ -348,7 +359,8 @@ void ChatModel::resendMessage (int id) {
}
shared_ptr message = static_pointer_cast(entry.second);
- if (message->getState() != linphone::ChatMessageStateNotDelivered) {
+ int state = message->getState();
+ if (state != linphone::ChatMessageStateNotDelivered && state != linphone::ChatMessageStateFileTransferError) {
qWarning() << QStringLiteral("Unable to resend message: %1. Bad state.").arg(id);
return;
}
@@ -381,6 +393,45 @@ void ChatModel::sendFileMessage (const QString &path) {
emit messageSent(message);
}
+void ChatModel::downloadFile (int id, const QString &download_path) {
+ if (!m_chat_room)
+ return;
+
+ if (id < 0 || id > m_entries.count()) {
+ qWarning() << QStringLiteral("Entry %1 not exists.").arg(id);
+ return;
+ }
+
+ const ChatEntryData &entry = m_entries[id];
+ if (entry.first["type"] != EntryType::MessageEntry) {
+ qWarning() << QStringLiteral("Unable to download entry %1. It's not a message.").arg(id);
+ return;
+ }
+
+ shared_ptr message = static_pointer_cast(entry.second);
+ if (!message->getFileTransferInformation()) {
+ qWarning() << QStringLiteral("Entry %1 is not a file message.").arg(id);
+ return;
+ }
+
+ int state = message->getState();
+ if (state != linphone::ChatMessageStateDelivered && state != linphone::ChatMessageStateFileTransferDone) {
+ qWarning() << QStringLiteral("Unable to download file of entry %1. It was not uploaded.").arg(id);
+ return;
+ }
+
+ message->setFileTransferFilepath(
+ ::Utils::qStringToLinphoneString(download_path.startsWith("file://")
+ ? download_path.mid(sizeof("file://") - 1)
+ : download_path
+ )
+ );
+ message->setListener(m_message_handlers);
+
+ if (message->downloadFile() < 0)
+ qWarning() << QStringLiteral("Unable to download file of entry %1.").arg(id);
+}
+
// -----------------------------------------------------------------------------
void ChatModel::fillMessageEntry (QVariantMap &dest, const shared_ptr &message) {
diff --git a/tests/src/components/chat/ChatModel.hpp b/tests/src/components/chat/ChatModel.hpp
index 1a18af568..c640a82ec 100644
--- a/tests/src/components/chat/ChatModel.hpp
+++ b/tests/src/components/chat/ChatModel.hpp
@@ -70,6 +70,8 @@ public:
void sendFileMessage (const QString &path);
+ void downloadFile (int id, const QString &download_path);
+
signals:
void sipAddressChanged (const QString &sip_address);
void allEntriesRemoved ();
diff --git a/tests/src/components/chat/ChatProxyModel.cpp b/tests/src/components/chat/ChatProxyModel.cpp
index 47e0cff3c..8b3998119 100644
--- a/tests/src/components/chat/ChatProxyModel.cpp
+++ b/tests/src/components/chat/ChatProxyModel.cpp
@@ -109,6 +109,13 @@ void ChatProxyModel::sendFileMessage (const QString &path) {
static_cast(m_chat_model_filter->sourceModel())->sendFileMessage(path);
}
+void ChatProxyModel::downloadFile (int id, const QString &download_path) {
+ QModelIndex source_index = mapToSource(index(id, 0));
+ static_cast(m_chat_model_filter->sourceModel())->downloadFile(
+ m_chat_model_filter->mapToSource(source_index).row(), download_path
+ );
+}
+
// -----------------------------------------------------------------------------
bool ChatProxyModel::filterAcceptsRow (int source_row, const QModelIndex &) const {
diff --git a/tests/src/components/chat/ChatProxyModel.hpp b/tests/src/components/chat/ChatProxyModel.hpp
index 88535566e..aba11b114 100644
--- a/tests/src/components/chat/ChatProxyModel.hpp
+++ b/tests/src/components/chat/ChatProxyModel.hpp
@@ -28,6 +28,8 @@ public:
Q_INVOKABLE void sendFileMessage (const QString &path);
+ Q_INVOKABLE void downloadFile (int id, const QString &download_path);
+
signals:
void sipAddressChanged (const QString &sip_address);
void moreEntriesLoaded (int n);
diff --git a/tests/ui/modules/Linphone/Chat/FileMessage.qml b/tests/ui/modules/Linphone/Chat/FileMessage.qml
index 7829c57ab..7b7609b59 100644
--- a/tests/ui/modules/Linphone/Chat/FileMessage.qml
+++ b/tests/ui/modules/Linphone/Chat/FileMessage.qml
@@ -1,5 +1,6 @@
import QtQuick 2.7
import QtQuick.Controls 2.0
+import QtQuick.Dialogs 1.2
import QtQuick.Layouts 1.3
import Common 1.0
@@ -47,6 +48,8 @@ Row {
Rectangle {
id: rectangle
+ readonly property bool isNotDelivered: $chatEntry.status === ChatModel.MessageStatusNotDelivered
+
color: $chatEntry.isOutgoing
? ChatStyle.entry.message.outgoing.backgroundColor
: ChatStyle.entry.message.incoming.backgroundColor
@@ -169,6 +172,27 @@ Row {
}
}
}
+
+ MouseArea {
+ FileDialog {
+ id: fileDialog
+
+ folder: shortcuts.home
+ title: qsTr('downloadFileTitle')
+ selectExisting: false
+
+ onAccepted: proxyModel.downloadFile(index, fileUrl)
+ }
+
+ anchors.fill: parent
+ cursorShape: containsMouse
+ ? Qt.PointingHandCursor
+ : Qt.ArrowCursor
+ hoverEnabled: true
+
+ onClicked: fileDialog.open()
+ visible: !rectangle.isNotDelivered && !$chatEntry.isOutgoing
+ }
}
// -------------------------------------------------------------------------
@@ -182,10 +206,7 @@ Row {
id: icon
Icon {
- readonly property bool isNotDelivered:
- $chatEntry.status === ChatModel.MessageStatusNotDelivered
-
- icon: isNotDelivered ? 'chat_error' : 'chat_send'
+ icon: rectangle.isNotDelivered ? 'chat_error' : 'chat_send'
iconSize: ChatStyle.entry.message.outgoing.sendIconSize
MouseArea {