mirror of
https://gitlab.linphone.org/BC/public/linphone-desktop.git
synced 2026-01-17 03:18:07 +00:00
1623 lines
No EOL
86 KiB
QML
1623 lines
No EOL
86 KiB
QML
import QtQuick
|
|
import QtQuick.Layouts
|
|
import QtQuick.Effects
|
|
import QtQuick.Controls.Basic as Control
|
|
import Linphone
|
|
import EnumsToStringCpp
|
|
import UtilsCpp
|
|
import SettingsCpp
|
|
import DesktopToolsCpp
|
|
import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle
|
|
|
|
AbstractWindow {
|
|
id: mainWindow
|
|
flags: Qt.Window
|
|
minimumWidth: Math.round(1020 * DefaultStyle.dp)
|
|
minimumHeight: Math.round(700 * DefaultStyle.dp)
|
|
|
|
// modality: Qt.WindowModal
|
|
property CallGui call
|
|
|
|
property ConferenceGui conference: call && call.core.conference || null
|
|
property bool isConference: call ? call.core.isConference : false
|
|
|
|
property int conferenceLayout: call && call.core.conferenceVideoLayout || 0
|
|
property bool localVideoEnabled: call && call.core.localVideoEnabled
|
|
property bool remoteVideoEnabled: call && call.core.remoteVideoEnabled
|
|
|
|
property bool callTerminatedByUser: false
|
|
property var callState: call ? call.core.state : LinphoneEnums.CallState.Idle
|
|
property var transferState: call && call.core.transferState
|
|
|
|
onCallStateChanged: {
|
|
if (callState === LinphoneEnums.CallState.Connected) {
|
|
if (middleItemStackView.currentItem.objectName != "inCallItem") {
|
|
middleItemStackView.replace(inCallItem)
|
|
bottomButtonsLayout.visible = true
|
|
}
|
|
if (call.core.encryption === LinphoneEnums.MediaEncryption.Zrtp
|
|
&& !mainWindow.isConference && (!call.core.tokenVerified
|
|
|| call.core.isMismatch)) {
|
|
zrtpValidation.open()
|
|
}
|
|
} else if (callState === LinphoneEnums.CallState.Error
|
|
|| callState === LinphoneEnums.CallState.End) {
|
|
zrtpValidation.close()
|
|
callEnded(call)
|
|
}
|
|
}
|
|
|
|
onTransferStateChanged: {
|
|
console.log("Transfer state:", transferState)
|
|
if (mainWindow.transferState === LinphoneEnums.CallState.OutgoingInit) {
|
|
var callsWin = UtilsCpp.getCallsWindow()
|
|
if (!callsWin)
|
|
return
|
|
//: "Transfert en cours, veuillez patienter"
|
|
callsWin.showLoadingPopup(qsTr("call_transfer_in_progress_toast"))
|
|
} else if (mainWindow.transferState === LinphoneEnums.CallState.Error
|
|
|| mainWindow.transferState === LinphoneEnums.CallState.End
|
|
|| mainWindow.transferState === LinphoneEnums.CallState.Released
|
|
|| mainWindow.transferState === LinphoneEnums.CallState.Connected) {
|
|
var callsWin = UtilsCpp.getCallsWindow()
|
|
callsWin.closeLoadingPopup()
|
|
if (transferState === LinphoneEnums.CallState.Error)
|
|
UtilsCpp.showInformationPopup(
|
|
qsTr("information_popup_error_title"),
|
|
//: "Le transfert d'appel a échoué"
|
|
qsTr("call_transfer_failed_toast"), false,
|
|
mainWindow)
|
|
else if (transferState === LinphoneEnums.CallState.Connected) {
|
|
var mainWin = UtilsCpp.getMainWindow()
|
|
UtilsCpp.smartShowWindow(mainWin)
|
|
mainWin.transferCallSucceed()
|
|
}
|
|
}
|
|
}
|
|
onClosing: close => {
|
|
DesktopToolsCpp.screenSaverStatus = true
|
|
if (callsModel.haveCall) {
|
|
close.accepted = false
|
|
terminateAllCallsDialog.open()
|
|
}
|
|
if (middleItemStackView.currentItem.objectName === "waitingRoom")
|
|
middleItemStackView.replace(inCallItem)
|
|
}
|
|
|
|
function changeLayout(layoutIndex) {
|
|
if (layoutIndex == 0) {
|
|
console.log("Set Grid layout")
|
|
call.core.lSetConferenceVideoLayout(LinphoneEnums.ConferenceLayout.Grid)
|
|
} else if (layoutIndex == 1) {
|
|
console.log("Set AS layout")
|
|
call.core.lSetConferenceVideoLayout(LinphoneEnums.ConferenceLayout.ActiveSpeaker)
|
|
} else {
|
|
console.log("Set audio-only layout", layoutIndex)
|
|
call.core.lSetConferenceVideoLayout(LinphoneEnums.ConferenceLayout.AudioOnly)
|
|
}
|
|
}
|
|
|
|
function endCall(callToFinish) {
|
|
if (callToFinish)
|
|
callToFinish.core.lTerminate()
|
|
else {
|
|
if (!callsModel.haveCall) UtilsCpp.closeCallsWindow()
|
|
}
|
|
// var mainWin = UtilsCpp.getMainWindow()
|
|
// mainWin.goToCallHistory()
|
|
}
|
|
function callEnded(call) {
|
|
if (call && call.core.state === LinphoneEnums.CallState.Error) {
|
|
middleItemStackView.replace(inCallItem)
|
|
}
|
|
if (!callsModel.haveCall) {
|
|
if (call && call.core.isConference)
|
|
UtilsCpp.closeCallsWindow()
|
|
else {
|
|
bottomButtonsLayout.setButtonsEnabled(false)
|
|
autoCloseWindow.restart()
|
|
}
|
|
} else {
|
|
if (middleItemStackView.currentItem.objectName === "waitingRoom") {
|
|
middleItemStackView.replace(inCallItem)
|
|
}
|
|
mainWindow.call = callsModel.currentCall
|
|
}
|
|
}
|
|
|
|
signal setUpConferenceRequested(ConferenceInfoGui conferenceInfo)
|
|
function setupConference(conferenceInfo) {
|
|
middleItemStackView.replace(waitingRoom)
|
|
setUpConferenceRequested(conferenceInfo)
|
|
}
|
|
|
|
function joinConference(uri, options) {
|
|
if (uri.length === 0)
|
|
UtilsCpp.showInformationPopup(qsTr("information_popup_error_title"),
|
|
//: "La conférence n'a pas pu démarrer en raison d'une erreur d'uri."
|
|
qsTr("conference_error_empty_uri"),mainWindow)
|
|
else {
|
|
UtilsCpp.createCall(uri, options)
|
|
}
|
|
}
|
|
function cancelJoinConference() {
|
|
if (!callsModel.haveCall) {
|
|
UtilsCpp.closeCallsWindow()
|
|
} else {
|
|
mainWindow.call = callsModel.currentCall
|
|
}
|
|
middleItemStackView.replace(inCallItem)
|
|
}
|
|
function cancelAfterJoin() {
|
|
endCall(mainWindow.call)
|
|
}
|
|
|
|
Connections {
|
|
enabled: !!mainWindow.call
|
|
target: mainWindow.call && mainWindow.call.core
|
|
function onSecurityUpdated() {
|
|
if (mainWindow.call.core.encryption === LinphoneEnums.MediaEncryption.Zrtp) {
|
|
if (call.core.tokenVerified) {
|
|
zrtpValidation.close()
|
|
zrtpValidationToast.open()
|
|
} else {
|
|
zrtpValidation.open()
|
|
}
|
|
} else {
|
|
zrtpValidation.close()
|
|
}
|
|
}
|
|
function onTokenVerified() {
|
|
if (!zrtpValidation.isTokenVerified) {
|
|
zrtpValidation.securityError = true
|
|
} else
|
|
zrtpValidation.close()
|
|
}
|
|
}
|
|
|
|
Timer {
|
|
id: autoCloseWindow
|
|
interval: mainWindow.callTerminatedByUser ? 1500 : 2500
|
|
onTriggered: {
|
|
UtilsCpp.closeCallsWindow()
|
|
}
|
|
}
|
|
|
|
Dialog {
|
|
id: terminateAllCallsDialog
|
|
onAccepted: {
|
|
mainWindow.callTerminatedByUser = true
|
|
call.core.lTerminateAllCalls()
|
|
}
|
|
width: Math.round(278 * DefaultStyle.dp)
|
|
//: "Terminer tous les appels en cours ?"
|
|
title: qsTr("call_close_window_dialog_title")
|
|
//: "La fenêtre est sur le point d'être fermée. Cela terminera tous les appels en cours."
|
|
text: qsTr("call_close_window_dialog_message")
|
|
}
|
|
|
|
CallProxy {
|
|
id: callsModel
|
|
sourceModel: AppCpp.calls
|
|
onCurrentCallChanged: {
|
|
if (currentCall) {
|
|
mainWindow.call = currentCall
|
|
}
|
|
}
|
|
onHaveCallChanged: {
|
|
if (!haveCall) {
|
|
mainWindow.callEnded()
|
|
}
|
|
}
|
|
}
|
|
|
|
component BottomButton: Button {
|
|
id: bottomButton
|
|
required property string enabledIcon
|
|
property string disabledIcon
|
|
enabled: call != undefined
|
|
leftPadding: 0
|
|
rightPadding: 0
|
|
topPadding: 0
|
|
bottomPadding: 0
|
|
checkable: true
|
|
background: Rectangle {
|
|
anchors.fill: parent
|
|
color: bottomButton.enabled ? disabledIcon ? DefaultStyle.grey_500 : bottomButton.pressed || bottomButton.checked ? DefaultStyle.main2_400 : DefaultStyle.grey_500 : DefaultStyle.grey_600
|
|
radius: Math.round(71 * DefaultStyle.dp)
|
|
}
|
|
icon.source: disabledIcon
|
|
&& bottomButton.checked ? disabledIcon : enabledIcon
|
|
icon.width: Math.round(32 * DefaultStyle.dp)
|
|
icon.height: Math.round(32 * DefaultStyle.dp)
|
|
contentImageColor: DefaultStyle.grey_0
|
|
}
|
|
ZrtpAuthenticationDialog {
|
|
id: zrtpValidation
|
|
call: mainWindow.call
|
|
modal: true
|
|
closePolicy: Popup.NoAutoClose
|
|
}
|
|
Timer {
|
|
id: autoCloseZrtpToast
|
|
interval: 4000
|
|
onTriggered: {
|
|
zrtpValidationToast.y = -zrtpValidationToast.height * 2
|
|
}
|
|
}
|
|
Control.Control {
|
|
id: zrtpValidationToast
|
|
// width: Math.round(269 * DefaultStyle.dp)
|
|
y: -height * 2
|
|
z: 1
|
|
topPadding: Math.round(8 * DefaultStyle.dp)
|
|
bottomPadding: Math.round(8 * DefaultStyle.dp)
|
|
leftPadding: Math.round(50 * DefaultStyle.dp)
|
|
rightPadding: Math.round(50 * DefaultStyle.dp)
|
|
anchors.horizontalCenter: parent.horizontalCenter
|
|
clip: true
|
|
function open() {
|
|
if (mainWindow.isConference)
|
|
return
|
|
y = headerItem.height / 2
|
|
autoCloseZrtpToast.restart()
|
|
}
|
|
Behavior on y {
|
|
NumberAnimation {
|
|
duration: 1000
|
|
}
|
|
}
|
|
background: Rectangle {
|
|
anchors.fill: parent
|
|
color: DefaultStyle.grey_0
|
|
border.color: DefaultStyle.info_500_main
|
|
border.width: Math.max(Math.round(1 * DefaultStyle.dp), 1)
|
|
radius: Math.round(50 * DefaultStyle.dp)
|
|
}
|
|
contentItem: RowLayout {
|
|
// anchors.centerIn: parent
|
|
Image {
|
|
source: AppIcons.trusted
|
|
Layout.preferredWidth: Math.round(24 * DefaultStyle.dp)
|
|
Layout.preferredHeight: Math.round(24 * DefaultStyle.dp)
|
|
fillMode: Image.PreserveAspectFit
|
|
Layout.fillWidth: true
|
|
}
|
|
Text {
|
|
color: DefaultStyle.info_500_main
|
|
//: "Appareil authentifié"
|
|
text: qsTr("call_can_be_trusted_toast")
|
|
Layout.fillWidth: true
|
|
font {
|
|
pixelSize: Math.round(14 * DefaultStyle.dp)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/************************* CONTENT ********************************/
|
|
Rectangle {
|
|
anchors.fill: parent
|
|
color: DefaultStyle.grey_900
|
|
Keys.onEscapePressed: {
|
|
if (mainWindow.visibility == Window.FullScreen)
|
|
mainWindow.showNormal()
|
|
}
|
|
|
|
ColumnLayout {
|
|
anchors.fill: parent
|
|
spacing: Math.round(10 * DefaultStyle.dp)
|
|
anchors.bottomMargin: Math.round(10 * DefaultStyle.dp)
|
|
anchors.topMargin: Math.round(10 * DefaultStyle.dp)
|
|
Item {
|
|
id: headerItem
|
|
Layout.margins: Math.round(10 * DefaultStyle.dp)
|
|
Layout.leftMargin: Math.round(20 * DefaultStyle.dp)
|
|
Layout.fillWidth: true
|
|
Layout.minimumHeight: Math.round(25 * DefaultStyle.dp)
|
|
RowLayout {
|
|
anchors.left: parent.left
|
|
anchors.right: parent.right
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
spacing: Math.round(10 * DefaultStyle.dp)
|
|
RowLayout {
|
|
spacing: Math.round(10 * DefaultStyle.dp)
|
|
EffectImage {
|
|
id: callStatusIcon
|
|
Layout.preferredWidth: Math.round(30 * DefaultStyle.dp)
|
|
Layout.preferredHeight: Math.round(30 * DefaultStyle.dp)
|
|
// TODO : change with broadcast or meeting icon when available
|
|
imageSource: !mainWindow.call ? AppIcons.meeting : (mainWindow.callState === LinphoneEnums.CallState.End || mainWindow.callState === LinphoneEnums.CallState.Released) ? AppIcons.endCall : (mainWindow.callState === LinphoneEnums.CallState.Paused || mainWindow.callState === LinphoneEnums.CallState.PausedByRemote) ? AppIcons.pause : mainWindow.conference ? AppIcons.usersThree : mainWindow.call.core.dir === LinphoneEnums.CallDir.Outgoing ? AppIcons.arrowUpRight : AppIcons.arrowDownLeft
|
|
colorizationColor: !mainWindow.call
|
|
|| mainWindow.call.core.paused
|
|
|| mainWindow.callState
|
|
=== LinphoneEnums.CallState.Paused
|
|
|| mainWindow.callState
|
|
=== LinphoneEnums.CallState.PausedByRemote
|
|
|| mainWindow.callState
|
|
=== LinphoneEnums.CallState.End
|
|
|| mainWindow.callState
|
|
=== LinphoneEnums.CallState.Released
|
|
|| mainWindow.conference ? DefaultStyle.danger_500main : mainWindow.call.core.dir === LinphoneEnums.CallDir.Outgoing ? DefaultStyle.info_500_main : DefaultStyle.success_500main
|
|
onColorizationColorChanged: {
|
|
callStatusIcon.active = !callStatusIcon.active
|
|
callStatusIcon.active = !callStatusIcon.active
|
|
}
|
|
}
|
|
ColumnLayout {
|
|
spacing: Math.round(6 * DefaultStyle.dp)
|
|
RowLayout {
|
|
spacing: Math.round(10 * DefaultStyle.dp)
|
|
Text {
|
|
id: callStatusText
|
|
property string remoteName: mainWindow.call ? qsTr("call_dir").arg(EnumsToStringCpp.dirToString(mainWindow.call.core.dir)) : ""
|
|
Connections {
|
|
target: mainWindow
|
|
onCallStateChanged: {
|
|
if (mainWindow.callState === LinphoneEnums.CallState.Connected || mainWindow.callState === LinphoneEnums.CallState.StreamsRunning)
|
|
callStatusText.remoteName = mainWindow.call.core.remoteName
|
|
}
|
|
}
|
|
|
|
text: (mainWindow.callState === LinphoneEnums.CallState.End || mainWindow.callState === LinphoneEnums.CallState.Released)
|
|
//: Appel terminé
|
|
? qsTr("call_ended")
|
|
: mainWindow.call && (mainWindow.call.core.paused)
|
|
? (mainWindow.conference
|
|
//: Meeting paused
|
|
? qsTr("conference_paused")
|
|
: mainWindow.callState === LinphoneEnums.CallState.PausedByRemote
|
|
//: Call paused by remote
|
|
? qsTr("call_paused_by_remote")
|
|
//: Call paused
|
|
: qsTr("call_paused"))
|
|
: mainWindow.conference
|
|
? mainWindow.conference.core.subject
|
|
: remoteName
|
|
color: DefaultStyle.grey_0
|
|
font {
|
|
pixelSize: Typography.h3.pixelSize
|
|
weight: Typography.h3.weight
|
|
}
|
|
}
|
|
Rectangle {
|
|
visible: mainWindow.call
|
|
&& (mainWindow.callState
|
|
=== LinphoneEnums.CallState.Connected
|
|
|| mainWindow.callState
|
|
=== LinphoneEnums.CallState.StreamsRunning)
|
|
Layout.fillHeight: true
|
|
Layout.topMargin: Math.round(10 * DefaultStyle.dp)
|
|
Layout.bottomMargin: Math.round(2 * DefaultStyle.dp)
|
|
Layout.preferredWidth: Math.round(2 * DefaultStyle.dp)
|
|
color: DefaultStyle.grey_0
|
|
}
|
|
Text {
|
|
text: mainWindow.call ? UtilsCpp.formatElapsedTime(mainWindow.call.core.duration) : ""
|
|
color: DefaultStyle.grey_0
|
|
font {
|
|
pixelSize: Typography.h3.pixelSize
|
|
weight: Typography.h3.weight
|
|
}
|
|
visible: mainWindow.callState
|
|
=== LinphoneEnums.CallState.Connected
|
|
|| mainWindow.callState
|
|
=== LinphoneEnums.CallState.StreamsRunning
|
|
}
|
|
Text {
|
|
Layout.leftMargin: Math.round(14 * DefaultStyle.dp)
|
|
id: conferenceDate
|
|
text: mainWindow.conferenceInfo ? mainWindow.conferenceInfo.core.getStartEndDateString() : ""
|
|
color: DefaultStyle.grey_0
|
|
font {
|
|
pixelSize: Typography.p1.pixelSize
|
|
weight: Typography.p1.weight
|
|
capitalization: Font.Capitalize
|
|
}
|
|
}
|
|
}
|
|
RowLayout {
|
|
id: securityStateLayout
|
|
spacing: Math.round(5 * DefaultStyle.dp)
|
|
visible: false
|
|
Connections {
|
|
target: mainWindow
|
|
function onCallStateChanged() {
|
|
if (mainWindow.callState
|
|
=== LinphoneEnums.CallState.Connected)
|
|
securityStateLayout.visible = true
|
|
else if (mainWindow.callState
|
|
=== LinphoneEnums.CallState.End
|
|
|| mainWindow.callState
|
|
=== LinphoneEnums.CallState.Released)
|
|
securityStateLayout.visible = false
|
|
}
|
|
}
|
|
BusyIndicator {
|
|
//: Waiting for encryption
|
|
visible: encryptionStatusText.text === qsTr("call_waiting_for_encryption_info")
|
|
Layout.preferredWidth: Math.round(15 * DefaultStyle.dp)
|
|
Layout.preferredHeight: Math.round(15 * DefaultStyle.dp)
|
|
indicatorColor: DefaultStyle.grey_0
|
|
}
|
|
EffectImage {
|
|
Layout.preferredWidth: Math.round(15 * DefaultStyle.dp)
|
|
Layout.preferredHeight: Math.round(15 * DefaultStyle.dp)
|
|
colorizationColor: mainWindow.call
|
|
? mainWindow.call.core.encryption === LinphoneEnums.MediaEncryption.Srtp
|
|
? DefaultStyle.info_500_main
|
|
: mainWindow.call.core.encryption === LinphoneEnums.MediaEncryption.Zrtp
|
|
? mainWindow.call.core.isMismatch || !mainWindow.call.core.tokenVerified
|
|
? DefaultStyle.warning_600
|
|
: DefaultStyle.info_500_main
|
|
: DefaultStyle.grey_0
|
|
: "transparent"
|
|
visible: mainWindow.call
|
|
imageSource: mainWindow.call
|
|
? mainWindow.call.core.encryption === LinphoneEnums.MediaEncryption.Srtp
|
|
? AppIcons.lockSimple
|
|
: mainWindow.call && mainWindow.call.core.encryption === LinphoneEnums.MediaEncryption.Zrtp
|
|
? mainWindow.call.core.isMismatch || !mainWindow.call.core.tokenVerified
|
|
? AppIcons.warningCircle
|
|
: AppIcons.lockKey
|
|
: AppIcons.lockSimpleOpen
|
|
: ""
|
|
}
|
|
Text {
|
|
id: encryptionStatusText
|
|
text: mainWindow.conference
|
|
? qsTr("call_srtp_point_to_point_encrypted")
|
|
: mainWindow.call
|
|
? mainWindow.call.core.encryption === LinphoneEnums.MediaEncryption.Srtp
|
|
//: Appel chiffré de point à point
|
|
? qsTr("call_srtp_point_to_point_encrypted")
|
|
: mainWindow.call.core.encryption === LinphoneEnums.MediaEncryption.Zrtp
|
|
? mainWindow.call.core.isMismatch || !mainWindow.call.core.tokenVerified
|
|
//: Vérification nécessaire
|
|
? qsTr("call_zrtp_sas_validation_required")
|
|
//: Appel chiffré de bout en bout
|
|
: qsTr("call_zrtp_end_to_end_encrypted")
|
|
: mainWindow.call.core.encryption === LinphoneEnums.MediaEncryption.None
|
|
//: "Appel non chiffré"
|
|
? qsTr("call_not_encrypted")
|
|
: qsTr("call_waiting_for_encryption_info")
|
|
: ""
|
|
color: mainWindow.conference || mainWindow.call?.core.encryption === LinphoneEnums.MediaEncryption.Srtp
|
|
? DefaultStyle.info_500_main
|
|
: mainWindow.call
|
|
? mainWindow.call.core.encryption === LinphoneEnums.MediaEncryption.Zrtp
|
|
? mainWindow.call.core.isMismatch || !mainWindow.call.core.tokenVerified
|
|
? DefaultStyle.warning_600
|
|
: DefaultStyle.info_500_main
|
|
: DefaultStyle.grey_0
|
|
: DefaultStyle.grey_0
|
|
font {
|
|
pixelSize: Math.round(12 * DefaultStyle.dp)
|
|
weight: Math.round(400 * DefaultStyle.dp)
|
|
}
|
|
MouseArea {
|
|
anchors.fill: parent
|
|
hoverEnabled: true
|
|
cursorShape: containsMouse ? Qt.PointingHandCursor : Qt.ArrowCursor
|
|
onClicked: {
|
|
if (rightPanel.visible
|
|
&& rightPanel.contentLoader.item.objectName
|
|
=== "encryptionPanel")
|
|
rightPanel.visible = false
|
|
else {
|
|
rightPanel.visible = true
|
|
rightPanel.replace(encryptionPanel)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
Item {
|
|
Layout.fillWidth: true
|
|
}
|
|
}
|
|
}
|
|
}
|
|
Item {
|
|
Layout.fillWidth: true
|
|
}
|
|
EffectImage {
|
|
Layout.preferredWidth: Math.round(32 * DefaultStyle.dp)
|
|
Layout.preferredHeight: Math.round(32 * DefaultStyle.dp)
|
|
Layout.rightMargin: Math.round(30 * DefaultStyle.dp)
|
|
property int quality: mainWindow.call ? mainWindow.call.core.quality : 0
|
|
imageSource: quality >= 4 ? AppIcons.cellSignalFull : quality >= 3 ? AppIcons.cellSignalMedium : quality >= 2 ? AppIcons.cellSignalLow : AppIcons.cellSignalNone
|
|
colorizationColor: DefaultStyle.grey_0
|
|
MouseArea {
|
|
anchors.fill: parent
|
|
hoverEnabled: true
|
|
cursorShape: containsMouse ? Qt.PointingHandCursor : Qt.ArrowCursor
|
|
onClicked: {
|
|
if (rightPanel.visible
|
|
&& rightPanel.contentLoader.item.objectName
|
|
=== "statsPanel")
|
|
rightPanel.visible = false
|
|
else {
|
|
rightPanel.visible = true
|
|
rightPanel.replace(statsPanel)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Control.Control {
|
|
visible: mainWindow.call ? !!mainWindow.conference ? mainWindow.conference.core.isRecording : (mainWindow.call.core.recording || mainWindow.call.core.remoteRecording) : false
|
|
anchors.centerIn: parent
|
|
leftPadding: Math.round(14 * DefaultStyle.dp)
|
|
rightPadding: Math.round(14 * DefaultStyle.dp)
|
|
topPadding: Math.round(6 * DefaultStyle.dp)
|
|
bottomPadding: Math.round(6 * DefaultStyle.dp)
|
|
background: Rectangle {
|
|
anchors.fill: parent
|
|
color: DefaultStyle.grey_500
|
|
radius: Math.round(10 * DefaultStyle.dp)
|
|
}
|
|
contentItem: RowLayout {
|
|
spacing: Math.round(85 * DefaultStyle.dp)
|
|
RowLayout {
|
|
spacing: Math.round(15 * DefaultStyle.dp)
|
|
EffectImage {
|
|
imageSource: AppIcons.recordFill
|
|
colorizationColor: DefaultStyle.danger_500main
|
|
Layout.preferredWidth: Math.round(24 * DefaultStyle.dp)
|
|
Layout.preferredHeight: Math.round(24 * DefaultStyle.dp)
|
|
}
|
|
Text {
|
|
color: DefaultStyle.danger_500main
|
|
font.pixelSize: Math.round(14 * DefaultStyle.dp)
|
|
text: mainWindow.call
|
|
? mainWindow.call.core.recording
|
|
? mainWindow.conference
|
|
//: "Vous enregistrez la réunion"
|
|
? qsTr("conference_user_is_recording")
|
|
//: "Vous enregistrez l'appel"
|
|
: qsTr("call_user_is_recording")
|
|
: mainWindow.conference
|
|
//: "Un participant enregistre la réunion"
|
|
? qsTr("conference_remote_is_recording")
|
|
//: "%1 enregistre l'appel"
|
|
: qsTr("call_remote_recording").arg(mainWindow.call.core.remoteName)
|
|
: ""
|
|
}
|
|
}
|
|
BigButton {
|
|
visible: mainWindow.call
|
|
&& mainWindow.call.core.recording
|
|
//: "Arrêter l'enregistrement"
|
|
text: qsTr("call_stop_recording")
|
|
style: ButtonStyle.main
|
|
onPressed: mainWindow.call.core.lStopRecording()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
RowLayout {
|
|
Layout.fillWidth: true
|
|
Layout.fillHeight: true
|
|
spacing: Math.round(23 * DefaultStyle.dp)
|
|
Control.StackView {
|
|
id: middleItemStackView
|
|
initialItem: inCallItem
|
|
Layout.fillWidth: true
|
|
Layout.fillHeight: true
|
|
}
|
|
CallSettingsPanel {
|
|
id: rightPanel
|
|
Layout.fillHeight: true
|
|
Layout.rightMargin: Math.round(20 * DefaultStyle.dp)
|
|
Layout.preferredWidth: Math.round(393 * DefaultStyle.dp)
|
|
Layout.topMargin: Math.round(10 * DefaultStyle.dp)
|
|
property int currentIndex: 0
|
|
visible: false
|
|
onVisibleChanged: if(!visible) contentLoader.sourceComponent = null
|
|
function replace(id) {
|
|
rightPanel.customHeaderButtons = null
|
|
contentLoader.sourceComponent = id
|
|
}
|
|
headerStack.currentIndex: 0
|
|
headerValidateButtonText: qsTr("add")
|
|
|
|
// Do not consider padding for chat
|
|
Binding on topPadding {
|
|
when: rightPanel.contentLoader.item && rightPanel.contentLoader.item.objectName === "chatPanel"
|
|
value: 0
|
|
restoreMode: Binding.RestoreBindingOrValue
|
|
}
|
|
Binding on leftPadding {
|
|
when: rightPanel.contentLoader.item && rightPanel.contentLoader.item.objectName === "chatPanel"
|
|
value: 0
|
|
restoreMode: Binding.RestoreBindingOrValue
|
|
}
|
|
Binding on rightPadding {
|
|
when: rightPanel.contentLoader.item && rightPanel.contentLoader.item.objectName == "chatPanel"
|
|
value: 0
|
|
restoreMode: Binding.RestoreBindingOrValue
|
|
}
|
|
Connections {
|
|
target: rightPanel.contentLoader
|
|
function onItemChanged() {
|
|
if (rightPanel.contentLoader.item) {
|
|
if (rightPanel.contentLoader.item.objectName === "callTransferPanel") {
|
|
//: "Transférer %1 à…"
|
|
rightPanel.headerTitleText = qsTr("call_transfer_current_call_title").arg(mainWindow.call.core.remoteName)
|
|
}
|
|
else if (rightPanel.contentLoader.item.objectName === "newCallPanel") {
|
|
//: "Nouvel appel"
|
|
rightPanel.headerTitleText = qsTr("call_action_start_new_call")
|
|
}
|
|
else if (rightPanel.contentLoader.item.objectName === "dialerPanel") {
|
|
//: "Pavé numérique"
|
|
rightPanel.headerTitleText = qsTr("call_action_show_dialer")
|
|
}
|
|
else if (rightPanel.contentLoader.item.objectName === "changeLayoutPanel") {
|
|
//: "Modifier la disposition"
|
|
rightPanel.headerTitleText = qsTr("call_action_change_layout")
|
|
}
|
|
else if (rightPanel.contentLoader.item.objectName === "callListPanel") {
|
|
//: "Liste d'appel"
|
|
rightPanel.headerTitleText = qsTr("call_action_go_to_calls_list")
|
|
}
|
|
else if (rightPanel.contentLoader.item.objectName === "chatPanel") {
|
|
rightPanel.headerTitleText = ""
|
|
}
|
|
else if (rightPanel.contentLoader.item.objectName === "settingsPanel") {
|
|
//: "Paramètres"
|
|
rightPanel.headerTitleText = qsTr("call_action_go_to_settings")
|
|
}
|
|
else if (rightPanel.contentLoader.item.objectName === "screencastPanel") {
|
|
//: "Partage de votre écran"
|
|
rightPanel.headerTitleText = qsTr("conference_action_screen_sharing")
|
|
}
|
|
else if (rightPanel.contentLoader.item.objectName === "encryptionPanel") {
|
|
//: Chiffrement
|
|
rightPanel.headerTitleText = qsTr("call_encryption_title")
|
|
}
|
|
else if (rightPanel.contentLoader.item.objectName === "statsPanel") {
|
|
//: Statistiques
|
|
rightPanel.headerTitleText = qsTr("call_stats_title")
|
|
}
|
|
}
|
|
if (!rightPanel.contentLoader.item || rightPanel.contentLoader.item.objectName !== "participantListPanel") rightPanel.headerStack.currentIndex = 0
|
|
if (!rightPanel.contentLoader.item || rightPanel.contentLoader.item.objectName !== "callTransferPanel") transferCallButton.checked = false
|
|
if (!rightPanel.contentLoader.item || rightPanel.contentLoader.item.objectName !== "newCallPanel") newCallButton.checked = false
|
|
if (!rightPanel.contentLoader.item || rightPanel.contentLoader.item.objectName !== "callListPanel") callListButton.checked = false
|
|
if (!rightPanel.contentLoader.item || rightPanel.contentLoader.item.objectName !== "screencastPanel") screencastPanelButton.checked = false
|
|
if (!rightPanel.contentLoader.item || rightPanel.contentLoader.item.objectName !== "chatPanel") chatPanelButton.checked = false
|
|
if (!rightPanel.contentLoader.item || rightPanel.contentLoader.item.objectName !== "participantListPanel") participantListButton.checked = false
|
|
}
|
|
}
|
|
|
|
// Binding on rightPadding {
|
|
// when: rightPanel.contentLoader.item && rightPanel.contentLoader.item.objectName == "participantListView"
|
|
// value: Math.round(10 * DefaultStyle.dp)
|
|
// restoreMode: Binding.RestoreBindingOrValue
|
|
// }
|
|
|
|
Item {
|
|
id: numericPadContainer
|
|
anchors.bottom: parent.bottom
|
|
anchors.left: parent.left
|
|
anchors.right: parent.right
|
|
height: childrenRect.height
|
|
}
|
|
}
|
|
}
|
|
|
|
Component {
|
|
id: callTransferPanel
|
|
Control.Control {
|
|
objectName: "callTransferPanel"
|
|
width: parent.width
|
|
NewCallForm {
|
|
id: newCallForm
|
|
width: parent.width
|
|
height: rightPanel.contentItemHeight
|
|
Keys.onEscapePressed: event => {
|
|
rightPanel.visible = false
|
|
event.accepted = true
|
|
}
|
|
groupCallVisible: false
|
|
displayCurrentCalls: true
|
|
searchBarColor: DefaultStyle.grey_0
|
|
searchBarBorderColor: DefaultStyle.grey_200
|
|
onContactClicked: contact => {
|
|
var callsWin = UtilsCpp.getCallsWindow()
|
|
if (contact)
|
|
//: "Confirmer le transfert"
|
|
callsWin.showConfirmationLambdaPopup(qsTr("call_transfer_confirm_dialog_tittle"),
|
|
//: "Vous allez transférer %1 à %2."
|
|
qsTr("call_transfer_confirm_dialog_message").arg(mainWindow.call.core.remoteName).arg(contact.core.fullName), "",
|
|
function (confirmed) {
|
|
if (confirmed) {
|
|
mainWindow.transferCallToContact(mainWindow.call,contact,newCallForm)
|
|
}
|
|
})
|
|
}
|
|
onTransferCallToAnotherRequested: dest => {
|
|
var callsWin = UtilsCpp.getCallsWindow()
|
|
console.log("transfer to",dest)
|
|
callsWin.showConfirmationLambdaPopup(qsTr("call_transfer_confirm_dialog_tittle"),
|
|
qsTr("call_transfer_confirm_dialog_message").arg(mainWindow.call.core.remoteName).arg(dest.core.remoteName),"",
|
|
function (confirmed) {
|
|
if (confirmed) {
|
|
mainWindow.call.core.lTransferCallToAnother(dest.core.remoteAddress)
|
|
}
|
|
})
|
|
}
|
|
numPadPopup: numPadPopup
|
|
|
|
NumericPadPopup {
|
|
id: numPadPopup
|
|
parent: numericPadContainer
|
|
width: parent.width
|
|
roundedBottom: true
|
|
lastRowVisible: false
|
|
visible: false
|
|
leftPadding: Math.round(40 * DefaultStyle.dp)
|
|
rightPadding: Math.round(40 * DefaultStyle.dp)
|
|
topPadding: Math.round(41 * DefaultStyle.dp)
|
|
bottomPadding: Math.round(18 * DefaultStyle.dp)
|
|
Component.onCompleted: parent.height = height
|
|
}
|
|
}
|
|
}
|
|
}
|
|
Component {
|
|
id: newCallPanel
|
|
Control.Control {
|
|
objectName: "newCallPanel"
|
|
width: parent.width
|
|
NewCallForm {
|
|
id: newCallForm
|
|
width: parent.width
|
|
height: rightPanel.contentItemHeight
|
|
groupCallVisible: false
|
|
searchBarColor: DefaultStyle.grey_0
|
|
searchBarBorderColor: DefaultStyle.grey_200
|
|
numPadPopup: numericPad
|
|
onContactClicked: contact => {
|
|
mainWindow.startCallWithContact(
|
|
contact, false, rightPanel)
|
|
}
|
|
Connections {
|
|
target: mainWindow
|
|
function onCallChanged() {
|
|
if (newCallForm.Control.StackView.status === Control.StackView.Active)
|
|
rightPanel.visible = false
|
|
}
|
|
}
|
|
|
|
NumericPadPopup {
|
|
id: numericPad
|
|
width: parent.width
|
|
parent: numericPadContainer
|
|
roundedBottom: true
|
|
visible: newCallForm.searchBar.numericPadButton.checked
|
|
leftPadding: Math.round(40 * DefaultStyle.dp)
|
|
rightPadding: Math.round(40 * DefaultStyle.dp)
|
|
topPadding: Math.round(41 * DefaultStyle.dp)
|
|
bottomPadding: Math.round(18 * DefaultStyle.dp)
|
|
onLaunchCall: {
|
|
rightPanel.visible = false
|
|
UtilsCpp.createCall(newCallForm.searchBar.text)
|
|
}
|
|
Component.onCompleted: parent.height = height
|
|
}
|
|
}
|
|
}
|
|
}
|
|
Component {
|
|
id: dialerPanel
|
|
Control.Control {
|
|
id: dialerPanelContent
|
|
objectName: "dialerPanel"
|
|
width: parent.width
|
|
Keys.onEscapePressed: event => {
|
|
rightPanel.visible = false
|
|
event.accepted = true
|
|
}
|
|
FocusScope {
|
|
width: parent.width
|
|
height: rightPanel.contentItemHeight
|
|
ColumnLayout {
|
|
anchors.fill: parent
|
|
spacing: Math.round(41 * DefaultStyle.dp)
|
|
Item{Layout.fillHeight: true}
|
|
SearchBar {
|
|
id: searchBar
|
|
height: Math.round(45 * DefaultStyle.dp)
|
|
magnifierVisible: false
|
|
color: DefaultStyle.grey_0
|
|
borderColor: DefaultStyle.grey_200
|
|
placeholderText: ""
|
|
numericPadPopup: numPad
|
|
numericPadButton.visible: false
|
|
enabled: false
|
|
}
|
|
NumericPad {
|
|
id: numPad
|
|
Layout.alignment: Qt.AlignHCenter | Qt.AlignBottom
|
|
Layout.bottomMargin: Math.round(18 * DefaultStyle.dp)
|
|
currentCall: callsModel.currentCall
|
|
lastRowVisible: false
|
|
onLaunchCall: {
|
|
UtilsCpp.createCall(dialerTextInput.text)
|
|
}
|
|
Component.onCompleted: parent.height = height
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
Component {
|
|
id: changeLayoutPanel
|
|
ChangeLayoutForm {
|
|
objectName: "changeLayoutPanel"
|
|
width: parent.width
|
|
Keys.onEscapePressed: event => {
|
|
rightPanel.visible = false
|
|
event.accepted = true
|
|
}
|
|
call: mainWindow.call
|
|
onChangeLayoutRequested: index => {
|
|
mainWindow.changeLayout(index)
|
|
}
|
|
}
|
|
}
|
|
Component {
|
|
id: callListPanel
|
|
ColumnLayout {
|
|
objectName: "callListPanel"
|
|
Keys.onEscapePressed: event => {
|
|
rightPanel.visible = false
|
|
event.accepted = true
|
|
}
|
|
spacing: 0
|
|
Component {
|
|
id: mergeCallPopupButton
|
|
PopupButton {
|
|
visible: callsModel.count >= 2
|
|
id: popupbutton
|
|
popup.contentItem: IconLabelButton {
|
|
icon.source: AppIcons.arrowsMerge
|
|
icon.width: Math.round(32 * DefaultStyle.dp)
|
|
icon.height: Math.round(32 * DefaultStyle.dp)
|
|
//: call_action_merge_calls
|
|
text: qsTr("Merger tous les appels")
|
|
textSize: Math.round(14 * DefaultStyle.dp)
|
|
onClicked: {
|
|
callsModel.lMergeAll()
|
|
popupbutton.close()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
RoundedPane {
|
|
Layout.fillWidth: true
|
|
Layout.maximumHeight: rightPanel.height
|
|
visible: callList.contentHeight > 0
|
|
leftPadding: Math.round(16 * DefaultStyle.dp)
|
|
rightPadding: Math.round(6 * DefaultStyle.dp)
|
|
topPadding: Math.round(15 * DefaultStyle.dp)
|
|
bottomPadding: Math.round(16 * DefaultStyle.dp)
|
|
|
|
Layout.topMargin: Math.round(15 * DefaultStyle.dp)
|
|
Layout.bottomMargin: Math.round(16 * DefaultStyle.dp)
|
|
Layout.leftMargin: Math.round(16 * DefaultStyle.dp)
|
|
Layout.rightMargin: Math.round(16 * DefaultStyle.dp)
|
|
|
|
contentItem: CallListView {
|
|
id: callList
|
|
}
|
|
}
|
|
Item {
|
|
Layout.fillHeight: true
|
|
}
|
|
Connections {
|
|
target: rightPanel.contentLoader
|
|
function onItemChanged() {
|
|
if (rightPanel.contentLoader.item.objectName === "callListPanel") {
|
|
rightPanel.customHeaderButtons = mergeCallPopupButton.createObject(rightPanel)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
Component {
|
|
id: chatPanel
|
|
Control.Control {
|
|
objectName: "chatPanel"
|
|
width: parent.width
|
|
SelectedChatView {
|
|
id: chatView
|
|
width: parent.width
|
|
height: rightPanel.contentItemHeight
|
|
Keys.onEscapePressed: event => {
|
|
rightPanel.visible = false
|
|
event.accepted = true
|
|
}
|
|
call: mainWindow.call
|
|
property var chatObj: UtilsCpp.getCurrentCallChat(mainWindow.call)
|
|
chat: chatObj ? chatObj.value : null
|
|
}
|
|
Connections {
|
|
target: rightPanel.contentLoader
|
|
function onItemChanged() {
|
|
if (rightPanel.contentLoader.item.objectName === "chatPanel") {
|
|
rightPanel.customHeaderButtons = chatView.callHeaderContent
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
Component {
|
|
id: settingsPanel
|
|
MultimediaSettings {
|
|
id: inSettingsPanel
|
|
objectName: "settingsPanel"
|
|
Keys.onEscapePressed: event => {
|
|
rightPanel.visible = false
|
|
event.accepted = true
|
|
}
|
|
call: mainWindow.call
|
|
height: childrenRect.height
|
|
width: parent.width
|
|
}
|
|
}
|
|
Component {
|
|
id: screencastPanel
|
|
Control.Control {
|
|
objectName: "screencastPanel"
|
|
width: parent.width
|
|
height: contentChildren.height
|
|
Keys.onEscapePressed: event => {
|
|
rightPanel.visible = false
|
|
event.accepted = true
|
|
}
|
|
contentItem: ScreencastSettings {
|
|
id: screencastsettings
|
|
anchors.topMargin: Math.round(16 * DefaultStyle.dp)
|
|
width: parent.width
|
|
call: mainWindow.call
|
|
}
|
|
}
|
|
}
|
|
Component {
|
|
id: participantListPanel
|
|
Control.Control {
|
|
width: parent.width
|
|
objectName: "participantListPanel"
|
|
Keys.onEscapePressed: event => {
|
|
rightPanel.visible = false
|
|
event.accepted = true
|
|
}
|
|
Control.StackView {
|
|
id: participantsStack
|
|
width: parent.width
|
|
height: rightPanel.contentItemHeight
|
|
// anchors.fill: parent
|
|
// anchors.bottomMargin: Math.round(16 * DefaultStyle.dp)
|
|
// anchors.leftMargin: Math.round(17 * DefaultStyle.dp)
|
|
// anchors.rightMargin: Math.round(17 * DefaultStyle.dp)
|
|
initialItem: participantListComp
|
|
onCurrentItemChanged: rightPanel.headerStack.currentIndex = currentItem.Control.StackView.index
|
|
property list<string> selectedParticipants
|
|
|
|
Connections {
|
|
target: rightPanel
|
|
function onReturnRequested() {
|
|
participantsStack.pop()
|
|
}
|
|
}
|
|
|
|
Component {
|
|
id: participantListComp
|
|
ParticipantListView {
|
|
id: participantList
|
|
objectName: "participantListView"
|
|
call: mainWindow.call
|
|
height: contentHeight
|
|
width: parent.width
|
|
rightMargin: 0
|
|
Component {
|
|
id: headerbutton
|
|
PopupButton {
|
|
popup.contentItem: IconLabelButton {
|
|
icon.source: AppIcons.shareNetwork
|
|
//: Partager le lien de la réunion
|
|
text: qsTr("conference_share_link_title")
|
|
onClicked: {
|
|
UtilsCpp.copyToClipboard(mainWindow.conference ? mainWindow.conference.core.uri : mainWindow.call.core.remoteAddress)
|
|
//: Copié
|
|
showInformationPopup(qsTr("copied"),
|
|
//: Le lien de la réunion a été copié dans le presse-papier
|
|
qsTr("information_popup_meeting_address_copied_to_clipboard"),true)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
onVisibleChanged: if (visible) {
|
|
rightPanel.customHeaderButtons = headerbutton.createObject(rightPanel)
|
|
//: "Participants (%1)"
|
|
rightPanel.headerTitleText = qsTr("conference_participants_list_title").arg(count)
|
|
}
|
|
onAddParticipantRequested: participantsStack.push(addParticipantComp)
|
|
onCountChanged: {
|
|
rightPanel.headerTitleText = qsTr("conference_participants_list_title").arg(count)
|
|
}
|
|
Connections {
|
|
target: participantsStack
|
|
function onCurrentItemChanged() {
|
|
if (participantsStack.currentItem == participantList)
|
|
rightPanel.headerTitleText = qsTr("conference_participants_list_title").arg(participantList.count)
|
|
}
|
|
}
|
|
Connections {
|
|
target: rightPanel
|
|
function onValidateRequested() {
|
|
participantList.model.addAddresses(participantsStack.selectedParticipants)
|
|
participantsStack.pop()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
Component {
|
|
id: addParticipantComp
|
|
AddParticipantsForm {
|
|
id: addParticipantLayout
|
|
// height: childrenRect.height
|
|
// width: parent.width
|
|
searchBarColor: DefaultStyle.grey_0
|
|
searchBarBorderColor: DefaultStyle.grey_200
|
|
onSelectedParticipantsCountChanged: {
|
|
rightPanel.headerSubtitleText = qsTr("group_call_participant_selected", '', selectedParticipantsCount).arg(selectedParticipantsCount)
|
|
participantsStack.selectedParticipants = selectedParticipants
|
|
}
|
|
Connections {
|
|
target: participantsStack
|
|
function onCurrentItemChanged() {
|
|
if (participantsStack.currentItem == addParticipantLayout) {
|
|
rightPanel.headerTitleText = qsTr("meeting_schedule_add_participants_title")
|
|
rightPanel.headerSubtitleText = qsTr("group_call_participant_selected", '', addParticipantLayout.selectedParticipants.length).arg(addParticipantLayout.selectedParticipants.length)
|
|
} else {
|
|
rightPanel.headerSubtitleText = ""
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
Component {
|
|
id: encryptionPanel
|
|
EncryptionSettings {
|
|
objectName: "encryptionPanel"
|
|
call: mainWindow.call
|
|
width: parent.width
|
|
onEncryptionValidationRequested: zrtpValidation.open()
|
|
}
|
|
}
|
|
Component {
|
|
id: statsPanel
|
|
CallStatistics {
|
|
objectName: "statsPanel"
|
|
width: parent.width
|
|
call: mainWindow.call
|
|
}
|
|
}
|
|
Component {
|
|
id: waitingRoom
|
|
WaitingRoom {
|
|
id: waitingRoomIn
|
|
objectName: "waitingRoom"
|
|
Layout.alignment: Qt.AlignCenter
|
|
onSettingsButtonCheckedChanged: {
|
|
if (settingsButtonChecked) {
|
|
rightPanel.visible = true
|
|
rightPanel.replace(settingsPanel)
|
|
} else {
|
|
rightPanel.visible = false
|
|
}
|
|
}
|
|
Binding {
|
|
target: callStatusIcon
|
|
when: middleItemStackView.currentItem.objectName === "waitingRoom"
|
|
property: "imageSource"
|
|
value: AppIcons.usersThree
|
|
}
|
|
Binding {
|
|
target: callStatusText
|
|
when: middleItemStackView.currentItem.objectName === "waitingRoom"
|
|
property: "text"
|
|
value: waitingRoomIn.conferenceInfo ? waitingRoomIn.conferenceInfo.core.subject : ''
|
|
}
|
|
Binding {
|
|
target: conferenceDate
|
|
when: middleItemStackView.currentItem.objectName === "waitingRoom"
|
|
property: "text"
|
|
value: waitingRoomIn.conferenceInfo ? waitingRoomIn.conferenceInfo.core.startEndDateString : ''
|
|
}
|
|
Connections {
|
|
target: rightPanel
|
|
function onVisibleChanged() {
|
|
if (!rightPanel.visible) {
|
|
waitingRoomIn.settingsButtonChecked = false
|
|
}
|
|
}
|
|
}
|
|
Connections {
|
|
target: mainWindow
|
|
function onSetUpConferenceRequested(conferenceInfo) {
|
|
waitingRoomIn.conferenceInfo = conferenceInfo
|
|
}
|
|
}
|
|
onJoinConfRequested: uri => {
|
|
mainWindow.joinConference(uri, {
|
|
"microEnabled": microEnabled,
|
|
"localVideoEnabled": localVideoEnabled
|
|
})
|
|
}
|
|
onCancelJoiningRequested: mainWindow.cancelJoinConference()
|
|
onCancelAfterJoinRequested: mainWindow.cancelAfterJoin()
|
|
}
|
|
}
|
|
Component {
|
|
id: inCallItem
|
|
Loader {
|
|
property string objectName: "inCallItem"
|
|
asynchronous: true
|
|
sourceComponent: Item {
|
|
CallLayout {
|
|
anchors.fill: parent
|
|
anchors.leftMargin: Math.round(20 * DefaultStyle.dp)
|
|
anchors.rightMargin: rightPanel.visible ? 0 : Math.round(10 * DefaultStyle.dp) // Grid and AS have 10 in right margin (so apply -10 here)
|
|
anchors.topMargin: Math.round(10 * DefaultStyle.dp)
|
|
call: mainWindow.call
|
|
callTerminatedByUser: mainWindow.callTerminatedByUser
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
RowLayout {
|
|
id: bottomButtonsLayout
|
|
Layout.alignment: Qt.AlignHCenter
|
|
spacing: Math.round(58 * DefaultStyle.dp)
|
|
visible: middleItemStackView.currentItem.objectName == "inCallItem"
|
|
|
|
function refreshLayout() {
|
|
if (mainWindow.callState === LinphoneEnums.CallState.Connected
|
|
|| mainWindow.callState === LinphoneEnums.CallState.StreamsRunning
|
|
|| mainWindow.callState === LinphoneEnums.CallState.Paused
|
|
|| mainWindow.callState === LinphoneEnums.CallState.PausedByRemote) {
|
|
connectedCallButtons.visible = bottomButtonsLayout.visible
|
|
moreOptionsButton.visible = bottomButtonsLayout.visible
|
|
bottomButtonsLayout.layoutDirection = Qt.RightToLeft
|
|
} else if (mainWindow.callState === LinphoneEnums.CallState.OutgoingInit) {
|
|
connectedCallButtons.visible = false
|
|
bottomButtonsLayout.layoutDirection = Qt.LeftToRight
|
|
moreOptionsButton.visible = false
|
|
}
|
|
}
|
|
|
|
Connections {
|
|
target: mainWindow
|
|
function onCallStateChanged() {
|
|
bottomButtonsLayout.refreshLayout()
|
|
}
|
|
function onCallChanged() {
|
|
bottomButtonsLayout.refreshLayout()
|
|
}
|
|
}
|
|
function setButtonsEnabled(enabled) {
|
|
for (var i = 0; i < children.length; ++i) {
|
|
children[i].enabled = false
|
|
}
|
|
}
|
|
BigButton {
|
|
Layout.row: 0
|
|
icon.width: Math.round(32 * DefaultStyle.dp)
|
|
icon.height: Math.round(32 * DefaultStyle.dp)
|
|
//: "Terminer l'appel"
|
|
ToolTip.text: qsTr("call_action_end_call")
|
|
Layout.preferredWidth: Math.round(75 * DefaultStyle.dp)
|
|
Layout.preferredHeight: Math.round(55 * DefaultStyle.dp)
|
|
radius: Math.round(71 * DefaultStyle.dp)
|
|
style: ButtonStyle.phoneRed
|
|
Layout.column: mainWindow.callState == LinphoneEnums.CallState.OutgoingInit
|
|
|| mainWindow.callState
|
|
== LinphoneEnums.CallState.OutgoingProgress
|
|
|| mainWindow.callState
|
|
== LinphoneEnums.CallState.OutgoingRinging
|
|
|| mainWindow.callState
|
|
== LinphoneEnums.CallState.OutgoingEarlyMedia
|
|
|| mainWindow.callState == LinphoneEnums.CallState.IncomingReceived ? 0 : bottomButtonsLayout.columns - 1
|
|
onClicked: {
|
|
mainWindow.callTerminatedByUser = true
|
|
mainWindow.endCall(mainWindow.call)
|
|
}
|
|
}
|
|
RowLayout {
|
|
id: connectedCallButtons
|
|
visible: false
|
|
Layout.row: 0
|
|
Layout.column: 1
|
|
spacing: Math.round(10 * DefaultStyle.dp)
|
|
CheckableButton {
|
|
id: pauseButton
|
|
Layout.preferredWidth: Math.round(55 * DefaultStyle.dp)
|
|
Layout.preferredHeight: Math.round(55 * DefaultStyle.dp)
|
|
icon.width: Math.round(32 * DefaultStyle.dp)
|
|
icon.height: Math.round(32 * DefaultStyle.dp)
|
|
//: "Reprendre l'appel"
|
|
ToolTip.text: checked ? qsTr("call_action_resume_call")
|
|
//: "Mettre l'appel en pause"
|
|
: qsTr("call_action_pause_call")
|
|
background: Rectangle {
|
|
anchors.fill: parent
|
|
radius: Math.round(71 * DefaultStyle.dp)
|
|
color: parent.enabled ? parent.checked ? DefaultStyle.success_500main : parent.pressed ? DefaultStyle.main2_400 : DefaultStyle.grey_500 : DefaultStyle.grey_600
|
|
}
|
|
enabled: mainWindow.conference
|
|
|| mainWindow.callState != LinphoneEnums.CallState.PausedByRemote
|
|
icon.source: enabled
|
|
&& checked ? AppIcons.play : AppIcons.phonePause
|
|
checked: mainWindow.call
|
|
&& mainWindow.callState == LinphoneEnums.CallState.Paused
|
|
|| mainWindow.callState == LinphoneEnums.CallState.Pausing
|
|
|| (!mainWindow.conference
|
|
&& mainWindow.callState
|
|
== LinphoneEnums.CallState.PausedByRemote)
|
|
onClicked: {
|
|
mainWindow.call.core.lSetPaused(
|
|
!mainWindow.call.core.paused)
|
|
}
|
|
}
|
|
CheckableButton {
|
|
id: transferCallButton
|
|
visible: !mainWindow.conference
|
|
icon.source: AppIcons.transferCall
|
|
Layout.preferredWidth: Math.round(55 * DefaultStyle.dp)
|
|
Layout.preferredHeight: Math.round(55 * DefaultStyle.dp)
|
|
icon.width: Math.round(32 * DefaultStyle.dp)
|
|
icon.height: Math.round(32 * DefaultStyle.dp)
|
|
contentImageColor: DefaultStyle.grey_0
|
|
//: "Transférer l'appel"
|
|
ToolTip.text: qsTr("call_action_transfer_call")
|
|
onToggled: {
|
|
console.log("checked transfer changed", checked)
|
|
if (checked) {
|
|
rightPanel.visible = true
|
|
rightPanel.replace(callTransferPanel)
|
|
} else {
|
|
rightPanel.visible = false
|
|
}
|
|
}
|
|
}
|
|
CheckableButton {
|
|
id: newCallButton
|
|
checkable: true
|
|
icon.source: AppIcons.newCall
|
|
Layout.preferredWidth: Math.round(55 * DefaultStyle.dp)
|
|
Layout.preferredHeight: Math.round(55 * DefaultStyle.dp)
|
|
icon.width: Math.round(32 * DefaultStyle.dp)
|
|
icon.height: Math.round(32 * DefaultStyle.dp)
|
|
//: "Initier un nouvel appel"
|
|
ToolTip.text: qsTr("call_action_start_new_call_hint")
|
|
onToggled: {
|
|
console.log("checked newcall changed", checked)
|
|
if (checked) {
|
|
rightPanel.visible = true
|
|
rightPanel.replace(newCallPanel)
|
|
} else {
|
|
rightPanel.visible = false
|
|
}
|
|
}
|
|
}
|
|
CheckableButton {
|
|
id: callListButton
|
|
Layout.preferredWidth: Math.round(55 * DefaultStyle.dp)
|
|
Layout.preferredHeight: Math.round(55 * DefaultStyle.dp)
|
|
checkable: true
|
|
icon.source: AppIcons.callList
|
|
icon.width: Math.round(32 * DefaultStyle.dp)
|
|
icon.height: Math.round(32 * DefaultStyle.dp)
|
|
//: "Afficher la liste d'appels"
|
|
ToolTip.text: qsTr("call_display_call_list_hint")
|
|
onToggled: {
|
|
if (checked) {
|
|
rightPanel.visible = true
|
|
rightPanel.replace(callListPanel)
|
|
} else {
|
|
rightPanel.visible = false
|
|
}
|
|
}
|
|
}
|
|
}
|
|
RowLayout {
|
|
Layout.row: 0
|
|
Layout.column: mainWindow.callState == LinphoneEnums.CallState.OutgoingInit
|
|
|| mainWindow.callState
|
|
== LinphoneEnums.CallState.OutgoingProgress
|
|
|| mainWindow.callState
|
|
== LinphoneEnums.CallState.OutgoingRinging
|
|
|| mainWindow.callState
|
|
== LinphoneEnums.CallState.OutgoingEarlyMedia
|
|
|| mainWindow.callState == LinphoneEnums.CallState.IncomingReceived ? bottomButtonsLayout.columns - 1 : 0
|
|
spacing: Math.round(10 * DefaultStyle.dp)
|
|
CheckableButton {
|
|
id: videoCameraButton
|
|
visible: SettingsCpp.videoEnabled
|
|
enabled: mainWindow.conferenceInfo
|
|
|| (mainWindow.callState === LinphoneEnums.CallState.Connected
|
|
|| mainWindow.callState
|
|
=== LinphoneEnums.CallState.StreamsRunning)
|
|
iconUrl: AppIcons.videoCamera
|
|
checkedIconUrl: AppIcons.videoCameraSlash
|
|
//: "Désactiver la vidéo"
|
|
//: "Activer la vidéo"
|
|
ToolTip.text: mainWindow.localVideoEnabled ? qsTr("call_deactivate_video_hint") : qsTr("call_activate_video_hint")
|
|
checked: !mainWindow.localVideoEnabled
|
|
Layout.preferredWidth: Math.round(55 * DefaultStyle.dp)
|
|
Layout.preferredHeight: Math.round(55 * DefaultStyle.dp)
|
|
icon.width: Math.round(32 * DefaultStyle.dp)
|
|
icon.height: Math.round(32 * DefaultStyle.dp)
|
|
onClicked: mainWindow.call.core.lSetLocalVideoEnabled(
|
|
!mainWindow.call.core.localVideoEnabled)
|
|
}
|
|
CheckableButton {
|
|
iconUrl: AppIcons.microphone
|
|
ToolTip.text: mainWindow.call && mainWindow.call.core.microphoneMuted
|
|
//: "Activer le micro"
|
|
? qsTr("call_activate_microphone")
|
|
//: "Désactiver le micro"
|
|
: qsTr("call_deactivate_microphone")
|
|
checkedIconUrl: AppIcons.microphoneSlash
|
|
checked: mainWindow.call
|
|
&& mainWindow.call.core.microphoneMuted
|
|
Layout.preferredWidth: Math.round(55 * DefaultStyle.dp)
|
|
Layout.preferredHeight: Math.round(55 * DefaultStyle.dp)
|
|
icon.width: Math.round(32 * DefaultStyle.dp)
|
|
icon.height: Math.round(32 * DefaultStyle.dp)
|
|
onClicked: mainWindow.call.core.lSetMicrophoneMuted(
|
|
!mainWindow.call.core.microphoneMuted)
|
|
}
|
|
CheckableButton {
|
|
id: screencastPanelButton
|
|
iconUrl: AppIcons.screencast
|
|
visible: !!mainWindow.conference
|
|
//: Partager l'écran…
|
|
ToolTip.text: qsTr("call_share_screen_hint")
|
|
Layout.preferredWidth: Math.round(55 * DefaultStyle.dp)
|
|
Layout.preferredHeight: Math.round(55 * DefaultStyle.dp)
|
|
icon.width: Math.round(32 * DefaultStyle.dp)
|
|
icon.height: Math.round(32 * DefaultStyle.dp)
|
|
onToggled: {
|
|
if (checked) {
|
|
rightPanel.visible = true
|
|
rightPanel.replace(screencastPanel)
|
|
} else {
|
|
rightPanel.visible = false
|
|
}
|
|
}
|
|
}
|
|
CheckableButton {
|
|
id: chatPanelButton
|
|
iconUrl: AppIcons.chatTeardropText
|
|
//: Open chat…
|
|
ToolTip.text: qsTr("call_open_chat_hint")
|
|
Layout.preferredWidth: Math.round(55 * DefaultStyle.dp)
|
|
Layout.preferredHeight: Math.round(55 * DefaultStyle.dp)
|
|
icon.width: Math.round(32 * DefaultStyle.dp)
|
|
icon.height: Math.round(32 * DefaultStyle.dp)
|
|
onToggled: {
|
|
if (checked) {
|
|
rightPanel.visible = true
|
|
rightPanel.replace(chatPanel)
|
|
} else {
|
|
rightPanel.visible = false
|
|
}
|
|
}
|
|
}
|
|
CheckableButton {
|
|
visible: false
|
|
checkable: false
|
|
iconUrl: AppIcons.handWaving
|
|
//: "Lever la main"
|
|
ToolTip.text: qsTr("call_rise_hand_hint")
|
|
Layout.preferredWidth: Math.round(55 * DefaultStyle.dp)
|
|
Layout.preferredHeight: Math.round(55 * DefaultStyle.dp)
|
|
icon.width: Math.round(32 * DefaultStyle.dp)
|
|
icon.height: Math.round(32 * DefaultStyle.dp)
|
|
}
|
|
CheckableButton {
|
|
visible: false
|
|
iconUrl: AppIcons.smiley
|
|
//: "Envoyer une réaction"
|
|
ToolTip.text: qsTr("call_send_reaction_hint")
|
|
Layout.preferredWidth: Math.round(55 * DefaultStyle.dp)
|
|
Layout.preferredHeight: Math.round(55 * DefaultStyle.dp)
|
|
icon.width: Math.round(32 * DefaultStyle.dp)
|
|
icon.height: Math.round(32 * DefaultStyle.dp)
|
|
}
|
|
CheckableButton {
|
|
id: participantListButton
|
|
//: "Gérer les participants"
|
|
ToolTip.text: qsTr("call_manage_participants_hint")
|
|
visible: mainWindow.conference
|
|
iconUrl: AppIcons.usersTwo
|
|
Layout.preferredWidth: Math.round(55 * DefaultStyle.dp)
|
|
Layout.preferredHeight: Math.round(55 * DefaultStyle.dp)
|
|
icon.width: Math.round(32 * DefaultStyle.dp)
|
|
icon.height: Math.round(32 * DefaultStyle.dp)
|
|
onToggled: {
|
|
if (checked) {
|
|
rightPanel.visible = true
|
|
rightPanel.replace(participantListPanel)
|
|
} else {
|
|
rightPanel.visible = false
|
|
}
|
|
}
|
|
}
|
|
PopupButton {
|
|
id: moreOptionsButton
|
|
//: "Plus d'options…"
|
|
ToolTip.text: qsTr("call_more_options_hint")
|
|
Layout.preferredWidth: Math.round(55 * DefaultStyle.dp)
|
|
Layout.preferredHeight: Math.round(55 * DefaultStyle.dp)
|
|
popup.topPadding: Math.round(20 * DefaultStyle.dp)
|
|
popup.bottomPadding: Math.round(20 * DefaultStyle.dp)
|
|
popup.leftPadding: Math.round(10 * DefaultStyle.dp)
|
|
popup.rightPadding: Math.round(10 * DefaultStyle.dp)
|
|
style: ButtonStyle.checkable
|
|
icon.width: Math.round(32 * DefaultStyle.dp)
|
|
icon.height: Math.round(32 * DefaultStyle.dp)
|
|
|
|
Connections {
|
|
target: moreOptionsButton.popup
|
|
function onOpened() {
|
|
moreOptionsButton.popup.y = -moreOptionsButton.popup.height
|
|
- moreOptionsButton.popup.padding
|
|
}
|
|
}
|
|
popup.contentItem: ColumnLayout {
|
|
id: optionsList
|
|
spacing: Math.round(5 * DefaultStyle.dp)
|
|
|
|
IconLabelButton {
|
|
Layout.fillWidth: true
|
|
visible: mainWindow.conference
|
|
icon.source: AppIcons.layout
|
|
icon.width: Math.round(32 * DefaultStyle.dp)
|
|
icon.height: Math.round(32 * DefaultStyle.dp)
|
|
//: "Modifier la disposition"
|
|
text: qsTr("call_action_change_conference_layout")
|
|
style: ButtonStyle.noBackground
|
|
onClicked: {
|
|
rightPanel.visible = true
|
|
rightPanel.replace(changeLayoutPanel)
|
|
moreOptionsButton.close()
|
|
}
|
|
}
|
|
IconLabelButton {
|
|
Layout.fillWidth: true
|
|
icon.source: AppIcons.fullscreen
|
|
//: "Mode Plein écran"
|
|
text: qsTr("call_action_full_screen")
|
|
icon.width: Math.round(32 * DefaultStyle.dp)
|
|
icon.height: Math.round(32 * DefaultStyle.dp)
|
|
checkable: true
|
|
style: ButtonStyle.noBackground
|
|
Binding on checked {
|
|
value: mainWindow.visibility === Window.FullScreen
|
|
}
|
|
onToggled: {
|
|
if (checked) {
|
|
mainWindow.showFullScreen()
|
|
} else {
|
|
mainWindow.showNormal()
|
|
}
|
|
moreOptionsButton.close()
|
|
}
|
|
}
|
|
IconLabelButton {
|
|
Layout.fillWidth: true
|
|
icon.source: AppIcons.dialer
|
|
text: qsTr("call_action_show_dialer")
|
|
icon.width: Math.round(32 * DefaultStyle.dp)
|
|
icon.height: Math.round(32 * DefaultStyle.dp)
|
|
style: ButtonStyle.noBackground
|
|
onClicked: {
|
|
rightPanel.visible = true
|
|
rightPanel.replace(dialerPanel)
|
|
moreOptionsButton.close()
|
|
}
|
|
}
|
|
IconLabelButton {
|
|
Layout.fillWidth: true
|
|
checkable: true
|
|
style: ButtonStyle.noBackground
|
|
icon.width: Math.round(32 * DefaultStyle.dp)
|
|
icon.height: Math.round(32 * DefaultStyle.dp)
|
|
visible: mainWindow.call
|
|
&& !mainWindow.conference
|
|
&& !SettingsCpp.disableCallRecordings
|
|
enabled: mainWindow.call
|
|
&& mainWindow.call.core.recordable
|
|
icon.source: AppIcons.recordFill
|
|
checked: mainWindow.call
|
|
&& mainWindow.call.core.recording
|
|
hoveredImageColor: contentImageColor
|
|
contentImageColor: mainWindow.call
|
|
&& mainWindow.call.core.recording ? DefaultStyle.danger_500main : DefaultStyle.main2_500main
|
|
text: mainWindow.call && mainWindow.call.core.recording
|
|
//: "Terminer l'enregistrement"
|
|
? qsTr("call_action_stop_recording")
|
|
//: "Enregistrer l'appel"
|
|
: qsTr("call_action_record")
|
|
textColor: mainWindow.call
|
|
&& mainWindow.call.core.recording ? DefaultStyle.danger_500main : DefaultStyle.main2_500main
|
|
hoveredTextColor: textColor
|
|
onToggled: {
|
|
if (mainWindow.call)
|
|
if (mainWindow.call.core.recording)
|
|
mainWindow.call.core.lStopRecording(
|
|
)
|
|
else
|
|
mainWindow.call.core.lStartRecording()
|
|
}
|
|
}
|
|
IconLabelButton {
|
|
Layout.fillWidth: true
|
|
checkable: true
|
|
style: ButtonStyle.noBackground
|
|
icon.width: Math.round(32 * DefaultStyle.dp)
|
|
icon.height: Math.round(32 * DefaultStyle.dp)
|
|
icon.source: !mainWindow.call
|
|
|| mainWindow.call.core.speakerMuted ? AppIcons.speakerSlash : AppIcons.speaker
|
|
contentImageColor: mainWindow.call
|
|
&& mainWindow.call.core.speakerMuted ? DefaultStyle.danger_500main : DefaultStyle.main2_500main
|
|
hoveredImageColor: contentImageColor
|
|
text: mainWindow.call && mainWindow.call.core.speakerMuted
|
|
//: "Activer le son"
|
|
? qsTr("call_activate_speaker_hint")
|
|
//: "Désactiver le son"
|
|
: qsTr("call_deactivate_speaker_hint")
|
|
textColor: mainWindow.call
|
|
&& mainWindow.call.core.speakerMuted ? DefaultStyle.danger_500main : DefaultStyle.main2_500main
|
|
hoveredTextColor: textColor
|
|
onCheckedChanged: {
|
|
if (mainWindow.call)
|
|
mainWindow.call.core.lSetSpeakerMuted(
|
|
!mainWindow.call.core.speakerMuted)
|
|
}
|
|
}
|
|
IconLabelButton {
|
|
Layout.fillWidth: true
|
|
icon.source: AppIcons.settings
|
|
icon.width: Math.round(32 * DefaultStyle.dp)
|
|
icon.height: Math.round(32 * DefaultStyle.dp)
|
|
//: "Paramètres"
|
|
text: qsTr("call_action_go_to_settings")
|
|
style: ButtonStyle.noBackground
|
|
onClicked: {
|
|
rightPanel.visible = true
|
|
rightPanel.replace(settingsPanel)
|
|
moreOptionsButton.close()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} |