diff --git a/linphone-desktop/assets/languages/en.ts b/linphone-desktop/assets/languages/en.ts
index 873bef5f4..e246e3f03 100644
--- a/linphone-desktop/assets/languages/en.ts
+++ b/linphone-desktop/assets/languages/en.ts
@@ -357,6 +357,13 @@ Server url not configured.
Display tooltips to discover Linphone Desktop
+
+ Incall
+
+ saveScreenshotTitle
+
+
+
MainWindow
diff --git a/linphone-desktop/assets/languages/fr.ts b/linphone-desktop/assets/languages/fr.ts
index 1047a8058..4e26fbdf4 100644
--- a/linphone-desktop/assets/languages/fr.ts
+++ b/linphone-desktop/assets/languages/fr.ts
@@ -345,6 +345,13 @@ Url du serveur non configurée.
Afficher les tooltips pour découvrir Linphone Desktop
+
+ Incall
+
+ saveScreenshotTitle
+
+
+
IncomingCall
diff --git a/linphone-desktop/src/components/camera/Camera.cpp b/linphone-desktop/src/components/camera/Camera.cpp
index fd52c5e1c..c1740eacc 100644
--- a/linphone-desktop/src/components/camera/Camera.cpp
+++ b/linphone-desktop/src/components/camera/Camera.cpp
@@ -1,8 +1,8 @@
-#include "Camera.hpp"
-
+#include
#include
#include
+#include "../../utils.hpp"
#include "../core/CoreManager.hpp"
#include "Camera.hpp"
@@ -52,15 +52,10 @@ QOpenGLFramebufferObject *CameraRenderer::createFramebufferObject (const QSize &
context_info->width = size.width();
context_info->height = size.height();
- shared_ptr linphone_call = m_camera->m_call->getLinphoneCall();
- linphone::CallState state = linphone_call->getState();
-
- if (state == linphone::CallStateConnected || state == linphone::CallStateStreamsRunning) {
- if (m_camera->m_is_preview)
- CoreManager::getInstance()->getCore()->setNativePreviewWindowId(context_info);
- else
- linphone_call->setNativeVideoWindowId(context_info);
- }
+ if (m_camera->m_is_preview)
+ CoreManager::getInstance()->getCore()->setNativePreviewWindowId(context_info);
+ else
+ m_camera->m_call->getLinphoneCall()->setNativeVideoWindowId(context_info);
return new QOpenGLFramebufferObject(size, format);
}
@@ -95,9 +90,30 @@ Camera::~Camera () {
}
QQuickFramebufferObject::Renderer *Camera::createRenderer () const {
- return new CameraRenderer(this);
+ m_renderer = new CameraRenderer(this);
+ return m_renderer;
}
+// -----------------------------------------------------------------------------
+
+void Camera::takeScreenshot () {
+ m_screenshot = m_renderer->framebufferObject()->toImage();
+}
+
+void Camera::saveScreenshot (const QString &path) {
+ QString formatted_path = path.startsWith("file://") ? path.mid(sizeof("file://") - 1) : path;
+ QFileInfo info(formatted_path);
+ QString extension = info.suffix();
+
+ m_screenshot.save(
+ formatted_path,
+ extension.size() > 0 ? ::Utils::qStringToLinphoneString(extension).c_str() : "jpg",
+ 100
+ );
+}
+
+// -----------------------------------------------------------------------------
+
void Camera::mousePressEvent (QMouseEvent *) {
setFocus(true);
}
diff --git a/linphone-desktop/src/components/camera/Camera.hpp b/linphone-desktop/src/components/camera/Camera.hpp
index 3f0385c52..c26a389c6 100644
--- a/linphone-desktop/src/components/camera/Camera.hpp
+++ b/linphone-desktop/src/components/camera/Camera.hpp
@@ -1,17 +1,20 @@
#ifndef CAMERA_H_
#define CAMERA_H_
-#include "../call/CallModel.hpp"
-
+#include
#include
#include
+#include "../call/CallModel.hpp"
+
// =============================================================================
class Camera;
struct ContextInfo;
class CameraRenderer : public QQuickFramebufferObject::Renderer {
+ friend class Camera;
+
public:
CameraRenderer (const Camera *camera);
~CameraRenderer () = default;
@@ -40,6 +43,9 @@ public:
QQuickFramebufferObject::Renderer *createRenderer () const override;
+ Q_INVOKABLE void takeScreenshot ();
+ Q_INVOKABLE void saveScreenshot (const QString &path);
+
signals:
void callChanged (CallModel *call);
void isPreviewChanged (bool is_preview);
@@ -54,6 +60,9 @@ private:
bool m_is_preview = false;
CallModel *m_call = nullptr;
ContextInfo *m_context_info;
+
+ mutable CameraRenderer *m_renderer;
+ QImage m_screenshot;
};
#endif // CAMERA_H_
diff --git a/linphone-desktop/ui/modules/Linphone/Chat/FileMessage.qml b/linphone-desktop/ui/modules/Linphone/Chat/FileMessage.qml
index 3eae0bc43..c86569c9d 100644
--- a/linphone-desktop/ui/modules/Linphone/Chat/FileMessage.qml
+++ b/linphone-desktop/ui/modules/Linphone/Chat/FileMessage.qml
@@ -183,8 +183,8 @@ Row {
id: fileDialog
folder: shortcuts.home
- title: qsTr('downloadFileTitle')
selectExisting: false
+ title: qsTr('downloadFileTitle')
onAccepted: proxyModel.downloadFile(index, fileUrl)
}
diff --git a/linphone-desktop/ui/views/App/Calls/Incall.qml b/linphone-desktop/ui/views/App/Calls/Incall.qml
index c38651ae5..5f043a695 100644
--- a/linphone-desktop/ui/views/App/Calls/Incall.qml
+++ b/linphone-desktop/ui/views/App/Calls/Incall.qml
@@ -1,4 +1,5 @@
import QtQuick 2.7
+import QtQuick.Dialogs 1.2
import QtQuick.Layouts 1.3
import Common 1.0
@@ -84,13 +85,31 @@ Rectangle {
id: cameraActions
anchors.right: parent.right
- active: Boolean(call.videoInputEnabled)
+ active: Boolean(call.videoInputEnabled) && call.status !== CallModel.CallStatusEnded
sourceComponent: ActionBar {
iconSize: CallStyle.header.iconSize
ActionButton {
icon: 'screenshot'
+
+ FileDialog {
+ id: fileDialog
+
+ folder: shortcuts.home
+ selectExisting: false
+ title: qsTr('saveScreenshotTitle')
+
+ onAccepted: cameraLoader.item.saveScreenshot(fileUrl)
+ }
+
+ onClicked: {
+ // TODO: At this moment, FileDialog does not support default filename, use this name in the future:
+ //'linphone ' + ((new Date()).toLocaleString(Qt.locale(), 'yyyy-MM-dd hh:mm:ss')) + '.jpg'
+
+ cameraLoader.item.takeScreenshot()
+ fileDialog.open()
+ }
}
ActionButton {
@@ -186,8 +205,9 @@ Rectangle {
}
Loader {
- anchors.centerIn: parent
+ id: cameraLoader
+ anchors.centerIn: parent
sourceComponent: call.videoInputEnabled ? camera : avatar
}
}
@@ -200,6 +220,8 @@ Rectangle {
Layout.fillWidth: true
Layout.preferredHeight: CallStyle.actionArea.height
+ visible: call.status !== CallModel.CallStatusEnded
+
GridLayout {
anchors {
left: parent.left