Commit 45e15a03 authored by Ronan Abhamon's avatar Ronan Abhamon

feat(src/components/camera/Camera): supports screenshots

parent e6fbc72e
...@@ -357,6 +357,13 @@ Server url not configured.</translation> ...@@ -357,6 +357,13 @@ Server url not configured.</translation>
<translation>Display tooltips to discover Linphone Desktop</translation> <translation>Display tooltips to discover Linphone Desktop</translation>
</message> </message>
</context> </context>
<context>
<name>Incall</name>
<message>
<source>saveScreenshotTitle</source>
<translation type="unfinished"></translation>
</message>
</context>
<context> <context>
<name>MainWindow</name> <name>MainWindow</name>
<message> <message>
......
...@@ -345,6 +345,13 @@ Url du serveur non configurée.</translation> ...@@ -345,6 +345,13 @@ Url du serveur non configurée.</translation>
<translation>Afficher les tooltips pour découvrir Linphone Desktop</translation> <translation>Afficher les tooltips pour découvrir Linphone Desktop</translation>
</message> </message>
</context> </context>
<context>
<name>Incall</name>
<message>
<source>saveScreenshotTitle</source>
<translation type="unfinished"></translation>
</message>
</context>
<context> <context>
<name>IncomingCall</name> <name>IncomingCall</name>
<message> <message>
......
#include "Camera.hpp" #include <QFileInfo>
#include <QOpenGLFunctions> #include <QOpenGLFunctions>
#include <QOpenGLTexture> #include <QOpenGLTexture>
#include "../../utils.hpp"
#include "../core/CoreManager.hpp" #include "../core/CoreManager.hpp"
#include "Camera.hpp" #include "Camera.hpp"
...@@ -52,15 +52,10 @@ QOpenGLFramebufferObject *CameraRenderer::createFramebufferObject (const QSize & ...@@ -52,15 +52,10 @@ QOpenGLFramebufferObject *CameraRenderer::createFramebufferObject (const QSize &
context_info->width = size.width(); context_info->width = size.width();
context_info->height = size.height(); context_info->height = size.height();
shared_ptr<linphone::Call> 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) if (m_camera->m_is_preview)
CoreManager::getInstance()->getCore()->setNativePreviewWindowId(context_info); CoreManager::getInstance()->getCore()->setNativePreviewWindowId(context_info);
else else
linphone_call->setNativeVideoWindowId(context_info); m_camera->m_call->getLinphoneCall()->setNativeVideoWindowId(context_info);
}
return new QOpenGLFramebufferObject(size, format); return new QOpenGLFramebufferObject(size, format);
} }
...@@ -95,9 +90,30 @@ Camera::~Camera () { ...@@ -95,9 +90,30 @@ Camera::~Camera () {
} }
QQuickFramebufferObject::Renderer *Camera::createRenderer () const { 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 *) { void Camera::mousePressEvent (QMouseEvent *) {
setFocus(true); setFocus(true);
} }
......
#ifndef CAMERA_H_ #ifndef CAMERA_H_
#define CAMERA_H_ #define CAMERA_H_
#include "../call/CallModel.hpp" #include <QImage>
#include <QOpenGLFramebufferObject> #include <QOpenGLFramebufferObject>
#include <QQuickFramebufferObject> #include <QQuickFramebufferObject>
#include "../call/CallModel.hpp"
// ============================================================================= // =============================================================================
class Camera; class Camera;
struct ContextInfo; struct ContextInfo;
class CameraRenderer : public QQuickFramebufferObject::Renderer { class CameraRenderer : public QQuickFramebufferObject::Renderer {
friend class Camera;
public: public:
CameraRenderer (const Camera *camera); CameraRenderer (const Camera *camera);
~CameraRenderer () = default; ~CameraRenderer () = default;
...@@ -40,6 +43,9 @@ public: ...@@ -40,6 +43,9 @@ public:
QQuickFramebufferObject::Renderer *createRenderer () const override; QQuickFramebufferObject::Renderer *createRenderer () const override;
Q_INVOKABLE void takeScreenshot ();
Q_INVOKABLE void saveScreenshot (const QString &path);
signals: signals:
void callChanged (CallModel *call); void callChanged (CallModel *call);
void isPreviewChanged (bool is_preview); void isPreviewChanged (bool is_preview);
...@@ -54,6 +60,9 @@ private: ...@@ -54,6 +60,9 @@ private:
bool m_is_preview = false; bool m_is_preview = false;
CallModel *m_call = nullptr; CallModel *m_call = nullptr;
ContextInfo *m_context_info; ContextInfo *m_context_info;
mutable CameraRenderer *m_renderer;
QImage m_screenshot;
}; };
#endif // CAMERA_H_ #endif // CAMERA_H_
...@@ -183,8 +183,8 @@ Row { ...@@ -183,8 +183,8 @@ Row {
id: fileDialog id: fileDialog
folder: shortcuts.home folder: shortcuts.home
title: qsTr('downloadFileTitle')
selectExisting: false selectExisting: false
title: qsTr('downloadFileTitle')
onAccepted: proxyModel.downloadFile(index, fileUrl) onAccepted: proxyModel.downloadFile(index, fileUrl)
} }
......
import QtQuick 2.7 import QtQuick 2.7
import QtQuick.Dialogs 1.2
import QtQuick.Layouts 1.3 import QtQuick.Layouts 1.3
import Common 1.0 import Common 1.0
...@@ -84,13 +85,31 @@ Rectangle { ...@@ -84,13 +85,31 @@ Rectangle {
id: cameraActions id: cameraActions
anchors.right: parent.right anchors.right: parent.right
active: Boolean(call.videoInputEnabled) active: Boolean(call.videoInputEnabled) && call.status !== CallModel.CallStatusEnded
sourceComponent: ActionBar { sourceComponent: ActionBar {
iconSize: CallStyle.header.iconSize iconSize: CallStyle.header.iconSize
ActionButton { ActionButton {
icon: 'screenshot' 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 { ActionButton {
...@@ -186,8 +205,9 @@ Rectangle { ...@@ -186,8 +205,9 @@ Rectangle {
} }
Loader { Loader {
anchors.centerIn: parent id: cameraLoader
anchors.centerIn: parent
sourceComponent: call.videoInputEnabled ? camera : avatar sourceComponent: call.videoInputEnabled ? camera : avatar
} }
} }
...@@ -200,6 +220,8 @@ Rectangle { ...@@ -200,6 +220,8 @@ Rectangle {
Layout.fillWidth: true Layout.fillWidth: true
Layout.preferredHeight: CallStyle.actionArea.height Layout.preferredHeight: CallStyle.actionArea.height
visible: call.status !== CallModel.CallStatusEnded
GridLayout { GridLayout {
anchors { anchors {
left: parent.left left: parent.left
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment